png.c revision eb3b22a03f31af7f724573d8537cd91fca06ee41
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
15294eb3931feb349dd87142c78503b779228f3e1a0fglennrp    intent,
1530cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15324eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1534faa852bad40107edae19405e76a299057668d795glennrp    pass,
1535faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1536faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1537faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1538faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1539faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
15404eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
15414eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
15424eb3931feb349dd87142c78503b779228f3e1a0fglennrp
15434eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
15444eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1546a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  LongPixelPacket
1547a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    transparent_color;
1548a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
15504383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1553faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1554faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1555faa852bad40107edae19405e76a299057668d795glennrp
1556faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1557faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1558faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1559faa852bad40107edae19405e76a299057668d795glennrp
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1570faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1571faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1572faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
15734eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_rowbytes,
15744eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
15754eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
1576faa852bad40107edae19405e76a299057668d795glennrp
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
1581cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
15905c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1592bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
160039992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1603eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
1604eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
1605eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
1619fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1622cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
162525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
163161b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
163261b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
163361b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
163461b4c957269727a0a2526edc2331881da8346100glennrp    {
163561b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
163661b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
163761b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
163861b4c957269727a0a2526edc2331881da8346100glennrp    }
163961b4c957269727a0a2526edc2331881da8346100glennrp#  endif
164061b4c957269727a0a2526edc2331881da8346100glennrp#endif
164161b4c957269727a0a2526edc2331881da8346100glennrp
164261b4c957269727a0a2526edc2331881da8346100glennrp
1643ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1646a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
1647a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
1648a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
1649a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
16500e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
16510e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
16520e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
16530e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
16540e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.opacity=65537;
16550e319739731741c52a6303723e0c8678a0df5579glennrp
1656cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
16574eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
1658cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
1659cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
1665cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
1666cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
1669cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
16750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
16830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1690cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
16910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1692faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1699cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17067b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
17077b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
17087b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
17097b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
17100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1716faa852bad40107edae19405e76a299057668d795glennrp
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1752991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1753991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1754991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1768991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1772faa852bad40107edae19405e76a299057668d795glennrp
1773faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1774faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1775faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1776faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1777faa852bad40107edae19405e76a299057668d795glennrp
1778faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1779faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1780faa852bad40107edae19405e76a299057668d795glennrp
1781faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1782faa852bad40107edae19405e76a299057668d795glennrp
1783faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1785faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1786faa852bad40107edae19405e76a299057668d795glennrp        {
1787faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1788faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1789faa852bad40107edae19405e76a299057668d795glennrp        }
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1791faa852bad40107edae19405e76a299057668d795glennrp
1792faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1794faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1798e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1799e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
18000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1803faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
18040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1807faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
18080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1811faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1814faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1815faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1820e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
1821e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
1822e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1823e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
1824e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
1825e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1826e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
1827e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1855cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1856cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        (mng_info->global_srgb_intent);
18570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1860cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1861cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
18620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1865e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1870faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1871faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1872faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
18730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1882faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1883faa852bad40107edae19405e76a299057668d795glennrp    {
1884faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1885faa852bad40107edae19405e76a299057668d795glennrp        {
1886faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1887faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1888faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1889faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1890faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1891faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1892faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1893faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1894faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1895faa852bad40107edae19405e76a299057668d795glennrp        }
1896faa852bad40107edae19405e76a299057668d795glennrp    }
18970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1898faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1915e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1917e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1918cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
1919cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
1920faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1921faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1922faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1923faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1926faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1928905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
1929905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
19300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1934e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1935e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1939faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1940faa852bad40107edae19405e76a299057668d795glennrp    {
1941faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1942faa852bad40107edae19405e76a299057668d795glennrp        {
1943faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1944faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1945faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1946faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1947faa852bad40107edae19405e76a299057668d795glennrp        }
1948faa852bad40107edae19405e76a299057668d795glennrp    }
1949faa852bad40107edae19405e76a299057668d795glennrp
1950faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19560881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19570881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19580881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1970e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1973823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
1974faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
19830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
1985faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
19910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1992faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2009faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2018faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2019faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2042faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2043faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2046faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20552cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2057faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2058faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2059faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20622cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20642cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
20652cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
20662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20672cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20682cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20692cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
20702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20712cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
20730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
20752cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
20760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20772cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
20782cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
20790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20802cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
20812cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
20820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20832cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
20842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
20852cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20862cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
20872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
20882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
20892cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20912cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
20922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
20940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
20972cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
20992cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2101faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2104faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2107faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2109f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2113e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2114e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2115e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2116e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2120a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2121faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2124a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212935ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
213035ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
213135ef824baa82511126ff0072ae30eee0da9c05a3cristy
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2136f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2138faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2139faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2140faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2141faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2142faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2143faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2149faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2154a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2155a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2156a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2157a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2158a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2159a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2160a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2161a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2162a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
2163a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.opacity= scale_to_short*ping_trans_color->gray;
216405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2165faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21670f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
21680f111984738842d27d04aed2a3f823d82a943506glennrp              {
21690f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21700f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
21710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21720f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21730f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
21740f111984738842d27d04aed2a3f823d82a943506glennrp              }
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2184faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2189faa852bad40107edae19405e76a299057668d795glennrp
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2191faa852bad40107edae19405e76a299057668d795glennrp
2192faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2193faa852bad40107edae19405e76a299057668d795glennrp
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2198bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2200bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2203faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2204faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2215faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2216faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2217faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2218faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2220befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2221befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2222befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2224befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2225befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2233faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2242bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2258faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2268bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2278bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2281faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
22820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2286bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2294147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2295cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2296cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2297147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2298147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2299147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2300147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2301147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2302147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
23037cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp     (void) FormatMagickString(msg,MaxTextExtent,
23047cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
23057cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp     (void) SetImageProperty(image,"PNG:IHDR.width,height    ",msg);
2306147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2307147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
2308147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.bit_depth       ",msg);
2309147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2310147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_color_type);
2311147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.color_type      ",msg);
2312147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2313147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",
2314147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        (int) ping_interlace_method);
2315147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.interlace_method",msg);
2316cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2317147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23240ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2325347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2326347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2330e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2334cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2348cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2349cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
23500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2352cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2353cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
23540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2355cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2364faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2371cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
23750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2376cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
2377cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
23780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
23820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
23847b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
23857b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
23867b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
23877b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
23880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2392ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
23930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2394ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2395ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2397c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2398c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2399c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2400c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2401c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2402c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2403c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2406c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2407c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2408c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2409c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2410c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
2411c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
2412c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        int
2413c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          depth;
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2415c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        depth=(ssize_t) ping_bit_depth;
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2417c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2418c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2419c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2420c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
24210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2422c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2423c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2424c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2425c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
24260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2427c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2428c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
24290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2430cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
2431c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (q == (PixelPacket *) NULL)
2434c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
24350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2436c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
2437c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp/* code deleted from version 6.6.6-8 */
2438c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#else  /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2440c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2442cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayQuantum,ping_pixels+row_offset,exception);
24430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2444c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2446cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayAlphaQuantum,ping_pixels+row_offset,exception);
24470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2448c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2450cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBAQuantum,ping_pixels+row_offset,exception);
24510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2453c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2454cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              IndexQuantum,ping_pixels+row_offset,exception);
24550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2456c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2458cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBQuantum,ping_pixels+row_offset,exception);
2459c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#endif
2460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2462c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2463a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2464a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2465a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2466a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2467c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
24695aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
24705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
24715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                   (q->opacity != OpaqueOpacity))
2472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2473a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2474a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2475a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2476a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2477c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
24804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
24814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
2482a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    (ScaleQuantumToShort(q->red) == transparent_color.red &&
2483a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->green) == transparent_color.green &&
2484a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->blue) == transparent_color.blue))
24854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2486a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2487a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2488a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
24894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
24904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
24914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2492c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                q++;
2493c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2494c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
24950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2496c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2499c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
25000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2501c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2502c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2503c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2505c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2506c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
25070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
25097a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2510c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25117a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25127a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25137a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2518c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2530faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2539bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2542faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
2543c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
2546c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2547cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25535c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2554cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2556c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2557faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
257947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2592bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
259847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2601bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
261247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2615faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
2625c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                if (q->opacity != OpaqueOpacity)
26260b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2631bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
263647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2642bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
265547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2656faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
2661c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
26620b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2667bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
26800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2681faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
2684afee4d36aae894a74306a3c492437ca55dce2badcristy                  q->opacity*=65537L;
268546f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
2686afee4d36aae894a74306a3c492437ca55dce2badcristy                  if (q->opacity != OpaqueOpacity)
26870b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
269147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
269547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2696faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
2699c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
27000b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
270747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
271047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
272080ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27257a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27267a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2727cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2728cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
272947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27307a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27317a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27327a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2734c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27357a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
273847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2742c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2745c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2746c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
2747c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2748c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
2749c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2750c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
2751c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2752c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
2753c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
27545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
27555aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27565aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
2757a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
27585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
27595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
2760c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
2761c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
2762c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2763b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2764b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27665c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27675c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2768aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27695c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27705c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27715c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27725c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27735c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2774aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27755c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
277647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27774eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2783cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2787cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
279447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2795faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
27993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2805c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2807c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2811c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2817c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
281847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
283247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2833a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
2834a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
2835a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2842c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2845c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2848a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
2849a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
2850a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
28510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
2853a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
2854a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
2855a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2860a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 0 /* I have not found a case where this is needed. */
28610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  q->opacity=(Quantum) OpaqueOpacity;
28644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
2865a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
28710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2872c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2874a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
2875c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2879b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2880b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2881b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
288247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2883eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
28844eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
28854eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
28864eb3931feb349dd87142c78503b779228f3e1a0fglennrp      status = (png_get_text(ping,ping_info,&text,&num_text) != 0);
28874eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
28884eb3931feb349dd87142c78503b779228f3e1a0fglennrp      status = (png_get_text(ping,end_info,&text,&num_text) != 0);
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28904eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
28914eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
28924eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
28934eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
28940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28954eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
28964eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28974eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
28980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28994eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29004eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
29014eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) Magick_png_read_raw_profile(image,image_info,text,(int) i);
29024eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
29034eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
29044eb3931feb349dd87142c78503b779228f3e1a0fglennrp
29054eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
29064eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
29074eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
29084eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
29094eb3931feb349dd87142c78503b779228f3e1a0fglennrp
29104eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
29114eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29124eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
29134eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
29144eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
29154eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (void) ThrowMagickException(&image->exception,GetMagickModule(),
29164eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  ResourceLimitError,"MemoryAllocationFailed","`%s'",
29174eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  image->filename);
29184eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
29194eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
29204eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
29214eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
29224eb3931feb349dd87142c78503b779228f3e1a0fglennrp
29234eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
29244eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
29254eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
29264eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
29274eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
29284eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
29294eb3931feb349dd87142c78503b779228f3e1a0fglennrp               (void) SetImageProperty(image,text[i].key,value);
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29314eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29334eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29344eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
29354eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29364eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29394eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
294097f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
29414eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
29424eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
295773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
296547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2998faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
30000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3001faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3002faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3003faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3004faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3005faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3006faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3007faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3008faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
30090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3010faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
302947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30350a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
30360a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp   /* Set image->matte to MagickTrue if the input colortype supports
30370a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
30380a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
30390a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
30400a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
30410a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
30420a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
30430a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        MagickTrue : MagickFalse;
30440a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3045cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3046cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3047cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3048cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3049cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
30504eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3051cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3052cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
3053cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) FormatMagickString(msg,MaxTextExtent,
3054613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
3055cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text                 ",msg);
3056cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3057cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3058cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3059cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3060cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) FormatMagickString(msg,MaxTextExtent,
3061cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
3062cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text-encoded profiles",msg);
3063cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3064cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3065cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
30665961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
30675961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) FormatMagickString(msg,MaxTextExtent,"%s",
30685961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
30695961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) SetImageProperty(image,"PNG:cHRM                 ",msg);
30705961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3071cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3072cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
30735961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
30745961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) FormatMagickString(msg,MaxTextExtent,"%s",
30755961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
30765961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) SetImageProperty(image,"PNG:bKGD                 ",msg);
30775961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
30785961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
30795961225e531a5f26ae179c1d919582d5cdaa44bbglennrp     (void) FormatMagickString(msg,MaxTextExtent,"%s",
30805961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3081cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3082cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
3083cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:iCCP                 ",msg);
3084cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
30854eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
30864eb3931feb349dd87142c78503b779228f3e1a0fglennrp        (void) SetImageProperty(image,"PNG:tRNS                 ",msg);
30874eb3931feb349dd87142c78503b779228f3e1a0fglennrp
30884eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
3089cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
30904eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
309107523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
309207523c7d2e40370804c2036295571e4b6426f94dglennrp            "intent=%d (See Rendering intent)",
30934eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (int) intent);
30944eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:sRGB                 ",msg);
30954eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
30964eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
30974eb3931feb349dd87142c78503b779228f3e1a0fglennrp
30984eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
30994eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
310007523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
310107523c7d2e40370804c2036295571e4b6426f94dglennrp            "gamma=%.8g (See Gamma, above)",
31024eb3931feb349dd87142c78503b779228f3e1a0fglennrp            file_gamma);
31034eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:gAMA                 ",msg);
31044eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3105cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31064eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3107cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
31084eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
310907523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
311007523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
31114eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
31124eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:pHYs                 ",msg);
31134eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31144eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3115cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31164eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
31174eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
31184eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
31194eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) FormatMagickString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
31204eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
31214eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:oFFs                 ",msg);
31224eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31234eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
31244eb3931feb349dd87142c78503b779228f3e1a0fglennrp
312507523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
312607523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
312707523c7d2e40370804c2036295571e4b6426f94dglennrp       {
312807523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
312907523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
313007523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
313107523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) SetImageProperty(image,"PNG:vpAg                 ",msg);
313207523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3133cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3134cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3140cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3142cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
31480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
316121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
316221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
317947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
318347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3186fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
319047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
319347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
319847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3199dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
320147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
320673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
320747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
321047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
322147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
32280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
32360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
323947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
324147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
32470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
325047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
32540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
326047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
32690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
327197f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
327297f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
327397f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
327497f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
327597f90e23c85b9c58387880125c29d8c99126f83aglennrp
327697f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
32780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33304383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
33314383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
33324383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3333bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3356bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3385fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
33880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
33970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
33990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
34020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
34300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
34330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3441e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3442e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
34460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
344947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
34530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
34590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
346247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
346947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3479bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
348547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
348847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
349347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3497f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
349847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3500f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
350147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
350447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
350847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
351247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
351647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
352047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
352447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
352847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
353447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
353747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
355373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
355447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
355747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
35600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
35670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
35710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
357873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
35790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
35850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
35960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
36000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
36030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
36120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
36150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
361803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
363547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
364247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
364547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
365447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
366403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
367947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
36990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
37298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
37300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
37408182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
37418182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
37428182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
37438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
37448182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
37458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
37468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
374847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3757e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3758cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
376947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37785eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
37795eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
37800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
378747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
37998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
38070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3815fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
38280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
385747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
38610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
38640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
38670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
38810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
38850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3886bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
389147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
38970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
390803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
39120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
39140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
39230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3925bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
393047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
39340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3936bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
39420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
395447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
395547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
39630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
39650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
39660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
39690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
39710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
39750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
39820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
39860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
402821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
402921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4049fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
406047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
406147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
406347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40643b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
406747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
406847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
407073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
40710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
407547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
407647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
40840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
40920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
410047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
41060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
41120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41264383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
412721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
412821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
41294383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4136bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4161bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4167bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4184bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
419338ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
419438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
419538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
421847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
421947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4225fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
42290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
42320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
423647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
423747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
423847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
423973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
42400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
424447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
424547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
425547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
425947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
426047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4263bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
426847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4311e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4312e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
43160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
43190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
43220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
432647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
432947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
433247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
43460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
43570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
436247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
43670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
43740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
43820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4383bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
43850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4389e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4391e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
43958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
43960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
43990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
44030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
44060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
44108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
44140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
44170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
44200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
442747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
44290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
44320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
44400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4441e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4442e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4443f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
44440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4446bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4448bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
44500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
44530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
44660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44698182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
44708182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
44710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
44740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
44830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4485e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
44860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4488e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
45020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
45310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
45340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
45410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
45420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
45440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
45450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4549e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4550f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
45510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4553e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4554f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
45640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
45710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
45940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
45970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
46020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
46050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
46080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
462047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
462347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
462447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
46300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4631bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
463835ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
46470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
46530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
465747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4663bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
467012560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4678bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46818182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
46880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
469547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
469647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
47008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
47018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
47038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
47058182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
47078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
47098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
47118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
471647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
472047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4728e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4729cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
473447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
473847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4741fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
474847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
475147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
47610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
476547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
47690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
47730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
477647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
477747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
477947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
478247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
478447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
479647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
48008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
48010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
48038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
48040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4805bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4806bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
48070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
48100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
48120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4815e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
481747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4820bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4821bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
48220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4823bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4824bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
48250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4826bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4827bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
48280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
48310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
48330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4836e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
483847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
48440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4848e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4849e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
485047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
48580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
48610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4870e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4871e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
48720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
487647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
488047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
488747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
49020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
49130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4917e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4918e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
493547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
494747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
497147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
497247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4981bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4984bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
499647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4999bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
500347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
500447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5007bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
502447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5031bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
503447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
503547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
50368182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
50370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5040e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5041e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
50420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
50450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
505647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
506047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
507247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
50790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5083e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5084f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
508547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
50900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
509547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
511347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
511747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
512447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
512747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
51440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
51470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
51500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
516147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
516747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
517347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
517647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
518247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
518547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
519147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
519447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
520047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
520347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
520947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
521247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
521847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
522147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
522747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
523147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
523947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
525847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
526547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
526847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
527547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
527847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
528347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
52998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
53018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
530547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
531447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
532047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
532547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5328bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
533847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
534147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
534447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
534747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
535047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
535347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
535647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
536447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
536747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
537047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
537547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
538547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
539247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
539547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
540147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
540947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
54118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5424bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5426bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
543447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
544147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
544547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
545247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
545547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
545647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
545747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5469e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5470e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
548747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
549447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
54990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
550947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
55200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5524e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5525e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
552947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
553647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
554347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
55490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
55520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
55610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
55700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
557647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
558047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
558547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5586bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
558747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
559947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
561247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
564547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
564847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
565047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
565147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
565347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56564e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
565747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
566047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
566347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
566547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
566647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
566847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
567247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
567547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
567747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
567847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
568047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56834e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
568447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
568747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
569047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
569247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
569347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
569547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5705bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5709bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
572447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
572547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
572947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
573147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5755bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
575947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
576847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
577947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
578447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
578747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
579047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
579347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5802e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
580847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
581747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
582047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
582547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
582847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5829bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5832bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
583447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
583747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
584147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5842bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
584847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5854bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
586047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5863fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
587447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
587947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5883bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5884bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5886bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5887bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5890bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
589247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5894bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5897bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
589947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
590947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
591547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
591847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5921bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
593047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
593347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
593647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5955e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
596547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5967bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5969bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5970bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
597147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5973bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
597447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5975bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5976bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
597747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5978bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5982bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
598347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
599147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
599647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
6002bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
6005bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
6008bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
6011bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
601447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
602447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
603047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
603347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
6038bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
604747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6057bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
606047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6061bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
606947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
610347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6119bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6120bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
612647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
613847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61612b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
61622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
61632b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
61642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
61652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
61662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
61672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
61682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
61690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
61708640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
61718640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6173d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
617547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6179bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6182d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6186d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
618847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
619047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
619447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
62050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
621647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
622047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
62330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
62360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
62410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
625247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
625647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
62610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
626647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
627247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
628047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
628547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
629147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
629447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
629747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
63050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
63080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
63110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
631647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
63220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
63240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6327e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6328e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
63290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
633747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
634047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6342e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
634347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6348e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6360bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
636547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
636847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
637147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
637447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
638347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
638647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
640347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
641347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
641647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6418e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6419e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
642047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6422f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6423f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
642447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6425f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6426e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6427e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6428f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6429f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
643047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
643447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
643747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
644025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
644547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
644847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
645147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
645625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6479bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6482bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
649547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
650147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
650947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
651347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
652147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
652447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
652947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
653247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
653547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
654147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
654647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
655147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
655447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
655947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
656447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
657447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
657847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
658547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
658847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
659347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
660147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
660647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
661447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
662147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
662847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
662918b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6630cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
663118b17443128598500357da7bff2f01683cf32890cristy#endif
663247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
666347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6665cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
6666cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
667125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
6747cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6754bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
67750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
67760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
67780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6797f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
679947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6800bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
680747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
681447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
681747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6823cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
68244383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
683847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
683947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
684047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
684247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
6846cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
684847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
684947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
685047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
685147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
685247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
685347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6854cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
6855cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
6856cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
685747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
685847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
685947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
686047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
686147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
686247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
686347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
6864cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
686547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
686747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
687047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6874b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6875b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6877b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6879b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6880b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6881b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6882b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6883b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6884b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6898cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6899cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6900e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6901e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
69025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
690339992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
690439992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
69075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
69085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
69095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
69175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
69185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
69195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6920bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
692458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
692521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
692658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
692758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
6928da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
6929fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
6930d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
69318d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
693239992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6933991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6934991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6935991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
693626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
693726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
693826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
6939e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
694026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
694126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
694226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
694326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
694426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
694526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
694626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6947e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
694826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
694926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
695026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
695126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
69520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
69530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
695482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
6955d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
6956d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6966cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
6969f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
69700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
69715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
69725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
69735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
69745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
69755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
69765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
69785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
69795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6981bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6986dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6987fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
6988f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
69898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
69908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
69918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6992dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6993dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6994dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6995dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6996dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6997dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
6999fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7001b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
7002b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
7003b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7005cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
70090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
70105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
70115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
70125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
70135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
70145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
70155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
70165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
70175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
70185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
70195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
70205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
70215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
70225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
70235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
70245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
70255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
70265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7027dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7028dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7029dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7030dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7031da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7032d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
70338d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
703439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7035991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7036991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7037991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7038991d11dd9c33e65872778b81aff1347cd2878154glennrp
70390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
70400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7041dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
70420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
70430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
70440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
70450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
70460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
70470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
70480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
70490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7050dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
70510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
70520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
70530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
70540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
70560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
70588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
70598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
70608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7061fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7062fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7063fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7064fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7065fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7066fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7067fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7068fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7069fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7070fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7071fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7072fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
7073fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
70760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70773241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
70783241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
70793241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
70803241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
70813241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
70823241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
70833241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7084a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7085a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7086a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7087a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7088a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7089a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7090a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7091a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7092a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7093a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7094a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7095a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
70962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70972b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
70982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
70992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
71002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
71012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
71022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
71032b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
71048640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
7105c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
71068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
71078640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
71088640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
71098640fb5e9b1094f35f8beab436f81661b8a99448glennrp
7110c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
7111e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
7112e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
7113e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * RGBA palette and run again, and finally to a simple 3-3-2-1 RGBA
7114e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * palette.  The final reduction can only fail if there are still 256
7115e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * colors present and one of them has both transparent and opaque instances.
7116c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
711782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
711882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
7119d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
712082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
7121d337164012450d70d62e71cf4a308a29004f7d57glennrp  for (j=0; j<5; j++)
7122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
7123d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
7124d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7125d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
7126d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
7127d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7128d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
7129d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
7130d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
7131d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
7132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
7133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7134d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * If image->matte is MagickFalse, we ignore the opacity channel
7135d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
7136d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7137d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
7138d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
7139d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
7140d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7141d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
7142d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
7143d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
71443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
714552a479ca718756af72f96e127f8256499ab68f76glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
714652a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 0 /* Shift */
714752a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 1 /* Scale */
714852a479ca718756af72f96e127f8256499ab68f76glennrp#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
714952a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 8
715052a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 0x0101
715152a479ca718756af72f96e127f8256499ab68f76glennrp#else
715252a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 24
715352a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 0x01010101
715452a479ca718756af72f96e127f8256499ab68f76glennrp#endif
715552a479ca718756af72f96e127f8256499ab68f76glennrp
7156d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   ExceptionInfo
7157d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *exception;
71588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7159d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
7160d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
71618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   PixelPacket
7163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
7164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
7165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
71668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register IndexPacket
7168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *indexes;
71698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register const PixelPacket
7171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *s,
7172d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *q;
7173d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7174fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   register PixelPacket
7175fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
7176fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
7180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7181d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7182d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7183d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7184d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
7185d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7186d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
7187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7188d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
718903812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7190d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
71913c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7192fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
71937ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
71947ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
71968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7197d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "        i    (red,green,blue,opacity)");
71982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7199d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
72007ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
7201d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7202d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7203d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7204d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7205d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7207d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
72087ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
72092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
7211d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7212d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
7213d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7217d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7218d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7220d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
7221d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
7223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
72242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7225d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7226d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
722783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7228d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
7229d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7230d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "        (zero means unknown)");
72317ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7232d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      Regenerate the colormap");
7234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
72357ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7236d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     exception=(&image->exception);
7237d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
7239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
7240fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
7241fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
72422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7243d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
7244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7245d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
72467ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (q == (PixelPacket *) NULL)
7248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
724997fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
7250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
7251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (image->matte == MagickFalse || q->opacity == OpaqueOpacity)
72538d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7254d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
72558d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
7257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0]=*q;
7259d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0].opacity=OpaqueOpacity;
7260d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
7261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
7264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7265d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(opaque+i, (PixelPacket *) q))
7266d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7267d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7269d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_opaque &&
7270d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque < 259)
7271d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
7273d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i] = *q;
7274d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i].opacity = OpaqueOpacity;
7275d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
72768d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
72778d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (q->opacity == TransparentOpacity)
72798d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
72818d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
7283d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[0]=*q;
7285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.red=(unsigned short)(q->red);
7286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.green=(unsigned short) (q->green);
7287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.blue=(unsigned short) (q->blue);
7288d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.gray=(unsigned short) (q->blue);
7289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
7290d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
7293d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(transparent+i, (PixelPacket *) q))
7295d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7297d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7298d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
7299d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
7300d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
7302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[i] = *q;
7303d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
73048d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
73058d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7306d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
7309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7310d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
7311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[0]=*q;
7313d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
7314d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
73158d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7316d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
7317d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(semitransparent+i,
7319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          (PixelPacket *) q) &&
7320d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          q->opacity == semitransparent[i].opacity)
7321d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7322d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
7325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
7326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
7328d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[i] = *q;
7329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7330d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
73318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
7332d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           q++;
7333d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
7334d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
73353c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7336d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (ping_exclude_bKGD == MagickFalse)
7337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7338d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
7339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
7340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7341d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
7342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7343a080bc32a4a8b2ffec83fd836a28753959175363glennrp             if (IsColorEqual(opaque+i, &image->background_color))
7344d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             break;
7345d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7346a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
734803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
7349d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i]=image->background_color;
7350d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i].opacity = OpaqueOpacity;
7351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               number_opaque++;
735203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
7353a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
7354a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7355a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
7356d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
73593241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7360a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
7361a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
7362a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
7363a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
7364a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
7365a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
7366a080bc32a4a8b2ffec83fd836a28753959175363glennrp
7367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7368d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
7370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
73723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7373d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
7374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7375d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
7376d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73773241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7378fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
7379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
7381d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
73823241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
7384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7385d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
7386d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
73886185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (q == (PixelPacket *) NULL)
7390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
73916185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7392d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
7393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
7394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
73956185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7396d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_color == MagickFalse)
7397d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7398d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
7400d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   {
7401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != s->green || s->red != s->blue)
7402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_color=MagickTrue;
7404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_non_bw=MagickTrue;
7405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          break;
7406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
74103241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
7412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
74156185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
7416d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != 0 && s->red != QuantumRange)
7417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
7419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7420d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
7423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           }
7425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
74264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
7427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
7428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         PixelPacket
7430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
7431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
7433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
7434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7435d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
7437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
7439d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
7441d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
74433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
7445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
74463241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7447d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
7448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
7449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
7451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
7452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
7455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
7456d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
7458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
7460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
7462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
7463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
7464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
7465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
7466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
7467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
7468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
7473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
7474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
74763241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
7478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
7479d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
7480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
7481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
7482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
74846185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
7485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
7486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
7488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
74892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
7492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
7495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (AcquireImageColormap(image,image_colors) ==
7497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
7498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               ThrowWriterException(ResourceLimitError,
7499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "MemoryAllocationFailed");
7500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
7502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
7503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
7505d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
7508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
7509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7510d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
7512d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7513d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7514fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
7515fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7516d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
7517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
7518d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              q=GetAuthenticPixels(image,0,y,image->columns,1,
7519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  exception);
75203c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (q == (PixelPacket *) NULL)
7522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
75233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7524d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              indexes=GetAuthenticIndexQueue(image);
7525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
7527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
752903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
7530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
7531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      image->colormap[i].opacity == q->opacity) &&
7532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (IsColorEqual(&image->colormap[i],
7533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         (PixelPacket *) q)))
75346185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
7535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    indexes[x]=(IndexPacket) i;
7536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
75376185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
753803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
7539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                q++;
7540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
7543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
7544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
7545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
7547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
7552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
7554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 "       i     (red,green,blue,opacity)");
755783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
7559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
756072988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
7561d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7562d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
7564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
7565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
7566d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
7567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
7568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].opacity);
7569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
75706185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
75716185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
75723c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7573d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
7574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
7576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
7577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
75783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
75813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
7583d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
7585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
758603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
7587d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7589d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
75906185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
7592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7593d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
7594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
75956185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7596d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7597d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
7599a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7601d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7602d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
7603a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7604d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
7605d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7606d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
7607d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7608d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7609d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7610d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
76116185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
761203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
761303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
7614d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
76153c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7616c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
7617c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7618fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7619c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
7620c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
7621c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
7622c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
7623c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
7624c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7625fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7626c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
7627c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     * opacity to 0 or OpaqueOpacity
7628c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7629c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (number_semitransparent != 0)
7630c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7631c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7632c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
7633fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7634c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
7635c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7636c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          r=GetAuthenticPixels(image,0,y,image->columns,1,
7637c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              exception);
7638fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7639c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (r == (PixelPacket *) NULL)
7640c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
7641fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7642c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
7643c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
764482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r->opacity = r->opacity > TransparentOpacity/2 ?
764582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                   TransparentOpacity : OpaqueOpacity;
7646c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              r++;
7647c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7648c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7649c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
7650c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
7651fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7652c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
7653c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
7654c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
7655c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                image->colormap[i].opacity =
765682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    image->colormap[i].opacity > TransparentOpacity/2 ?
765782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    TransparentOpacity : OpaqueOpacity;
7658c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7659c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7660c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7661c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7662c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
7663e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
7664e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
7665e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
7666c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7667d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
7668d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
7669d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7670d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7671d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
7672d337164012450d70d62e71cf4a308a29004f7d57glennrp
7673d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
7674d337164012450d70d62e71cf4a308a29004f7d57glennrp
7675d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.red=
7676d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7677d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.red) >> PNGK) & 0xf0)     )  |
7678d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7679d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7680d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.green=
7681d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7682d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.green) >> PNGK) & 0xf0)     )  |
7683d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7684d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7685d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.blue=
7686d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7687d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.blue) >> PNGK) & 0xf0)     )  |
7688d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7689d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7690d337164012450d70d62e71cf4a308a29004f7d57glennrp
7691d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7692d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7693d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
7694d337164012450d70d62e71cf4a308a29004f7d57glennrp
7695d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
7696d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7697d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
7698d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7699d337164012450d70d62e71cf4a308a29004f7d57glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7700d337164012450d70d62e71cf4a308a29004f7d57glennrp                exception);
7701d337164012450d70d62e71cf4a308a29004f7d57glennrp
7702d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (r == (PixelPacket *) NULL)
7703d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
7704d337164012450d70d62e71cf4a308a29004f7d57glennrp
7705d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
7706d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
7707d337164012450d70d62e71cf4a308a29004f7d57glennrp              if (r->opacity == TransparentOpacity)
7708d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7709d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red = image->background_color.red;
7710d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green = image->background_color.green;
7711d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue = image->background_color.blue;
7712d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7713d337164012450d70d62e71cf4a308a29004f7d57glennrp              else
7714d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7715d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red=
7716d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->red) >> PNGK) & 0xf0)    )  |
7717d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7718d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green=
7719d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->green) >> PNGK) & 0xf0)    )  |
7720d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7721d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue=
7722d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xf0)    )  |
7723d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7724d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7725d337164012450d70d62e71cf4a308a29004f7d57glennrp              r++;
7726d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
7727d337164012450d70d62e71cf4a308a29004f7d57glennrp
7728d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7729d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
7730d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7731d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7732d337164012450d70d62e71cf4a308a29004f7d57glennrp
7733d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
7734d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
7735d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7736d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
7737d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7738d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
7739d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
7740d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7741d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].red=
7742d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7743d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].red) >> PNGK) & 0xf0)     )  |
7744d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7745d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7746d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].green=
7747d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7748d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].green) >> PNGK) & 0xf0)     )  |
7749d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7750d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7751d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].blue=
7752d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7753d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].blue) >> PNGK) & 0xf0)     )  |
7754d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7755d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7756d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7757d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7758d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
7759d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
7760d337164012450d70d62e71cf4a308a29004f7d57glennrp
776182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
776282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
776382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
776482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
776582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
776682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
776782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
776882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
776982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.red=
777082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
777182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xe0)     )  |
777282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
777382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xe0) >> 3)  |
777482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
777582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xc0) >> 6)) * PNGM;
777682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.green=
777782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
777882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xe0)     )  |
777982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
778082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xe0) >> 3)  |
778182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
778282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xc0) >> 6)) * PNGM;
778382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.blue=
778482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
778582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xe0)     )  |
778682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
778782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xe0) >> 3)  |
778882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
778982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
779082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
779182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
779282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7793e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
779482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
779582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
779682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
779782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
779882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
779982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
780082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                exception);
780182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
780282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (r == (PixelPacket *) NULL)
780382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
780482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
780582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
780682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
780782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
780882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
780982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
781082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
781182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
781282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
781382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
781482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
781582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red=
781682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->red) >> PNGK) & 0xe0)    )  |
781782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xe0) >> 3)  |
781882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xc0) >> 6)) * PNGM;
781982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green=
782082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->green) >> PNGK) & 0xe0)    )  |
782182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xe0) >> 3)  |
782282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xc0) >> 6)) * PNGM;
782382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue=
782482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xe0)    )  |
782582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xe0) >> 3)  |
782682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
782782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
782882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r++;
782982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
783082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
783182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
783282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
783382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
783482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
783582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
783682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
783782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
783882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
783982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
784082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7841e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
784282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
784382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
784482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].red=
784582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
784682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xe0)     )  |
784782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
784882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xe0) >> 3)  |
784982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
785082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xc0) >> 6)) * PNGM;
785182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].green=
785282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
785382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xe0)     )  |
785482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
785582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xe0) >> 3)  |
785682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
785782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xc0) >> 6)) * PNGM;
785882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].blue=
785982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
786082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xe0)     )  |
786182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
786282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xe0) >> 3)  |
786382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
786482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
786582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
7866d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7867d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
786882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
7869c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7870c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors == 0 || image_colors > 256)
7871c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7872c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7873c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7874c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
7875c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7876c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.red=
7877770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7878770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xe0)     )  |
7879770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7880770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xe0) >> 3)  |
7881770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7882770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xc0) >> 6)) * PNGM;
7883c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.green=
7884770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7885770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xe0)     )  |
7886770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7887770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xe0) >> 3)  |
7888770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7889770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xc0) >> 6)) * PNGM;
7890c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.blue=
7891770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7892770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0)     )  |
7893770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7894770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 2)  |
7895770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7896770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 4)  |
7897770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7898770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
7899fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7900c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7901c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7902e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
7903fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7904c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
7905c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7906c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
7907c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
7908c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7909c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                exception);
79108d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7911c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (r == (PixelPacket *) NULL)
7912c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
7913c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7914c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
7915c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
791682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
791782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
791882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
791982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
792082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
792182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
792282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
792382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
792482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red=
792582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->red) >> PNGK) & 0xe0)    )  |
792682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xe0) >> 3)  |
792782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xc0) >> 6)) * PNGM;
792882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green=
792982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->green) >> PNGK) & 0xe0)    )  |
793082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xe0) >> 3)  |
793182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xc0) >> 6)) * PNGM;
793282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue=
793382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xc0)    )  |
793482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 2)  |
793582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 4)  |
793682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
793782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
793852a479ca718756af72f96e127f8256499ab68f76glennrp              r++;
7939c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
7940fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7941c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7942c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
7943c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7944c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7945c722dd852e8abe407c2846d39662f7ade9c234deglennrp
7946c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
7947c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
7948c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7949c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
7950c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7951e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
7952c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
7953c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
795452a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].red=
7955770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7956770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xe0)     )  |
7957770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7958770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xe0) >> 3)  |
7959770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7960770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xc0) >> 6)) * PNGM;
796152a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].green=
7962770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7963770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xe0)     )  |
7964770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7965770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xe0) >> 3)  |
7966770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7967770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xc0) >> 6)) * PNGM;
796852a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].blue=
7969770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7970770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0)     )  |
7971770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7972770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 2)  |
7973770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7974770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 4)  |
7975770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7976770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
7977c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7978c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
7979c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7980c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7981c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
7982fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
7983fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
7984fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7985fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
7986fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
7987fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
7988fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
79890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
79900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
79910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
79920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
79930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
79950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
79960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
79980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
79990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
80008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
80018d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         mng_info->write_png_colortype != (ssize_t) colortype)
80020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
80030b206f5daa453dc1035db5890cabc899736dc2d0glennrp
80040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
80050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
8006fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
8007fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
8008fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
80095a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
80105a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
80115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
8012fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
80135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
80145a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
8015fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8016fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
8017fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8018fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
8019fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
8020fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8021fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
8022fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
8023fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8024fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           ExceptionInfo
8025fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *exception;
8026fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8027fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           register const PixelPacket
8028fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
8029fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8030fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           exception=(&image->exception);
8031fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8032fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8033fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8034fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8035fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8036fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (q == (PixelPacket *) NULL)
8037fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8038fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8039fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8040fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
8041fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 if (q->opacity != TransparentOpacity &&
8042fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->red == ping_trans_color.red &&
8043fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->green == ping_trans_color.green &&
8044fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->blue == ping_trans_color.blue)
8045fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8046fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8047fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8048fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8049fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8050fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 q++;
8051fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8052fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8053fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8054fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8055fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8056fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8057fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8058fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8059fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Assuming that image->colormap[0] is the one transparent color
8060fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             * and that all others are opaque.
8061fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             */
8062fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
8063fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              for (i=1; i<image_colors; i++)
8064fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                if (image->colormap[i].red == image->colormap[0].red &&
8065fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].green == image->colormap[0].green &&
8066fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].blue == image->colormap[0].blue)
8067fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
8068fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8069fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8070fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8071fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8072fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8073fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8074fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8075fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8076fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8077fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8078fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8079fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8080fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8081fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8082fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8083fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8084fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8085fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8086fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
80873c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
80883c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
80893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
80903c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8091f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
80923c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
809383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
80940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
80951273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
809752a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
809852a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
809952a479ca718756af72f96e127f8256499ab68f76glennrp    {
810052a479ca718756af72f96e127f8256499ab68f76glennrp      image_info=DestroyImageInfo(image_info);
810152a479ca718756af72f96e127f8256499ab68f76glennrp      image=DestroyImage(image);
810215e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp      (void) ThrowMagickException(&IMimage->exception,
810315e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          GetMagickModule(),CoderError,
810415e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
810515e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "`%s'",IMimage->filename);
810652a479ca718756af72f96e127f8256499ab68f76glennrp#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
810752a479ca718756af72f96e127f8256499ab68f76glennrp      UnlockSemaphoreInfo(ping_semaphore);
810852a479ca718756af72f96e127f8256499ab68f76glennrp#endif
810952a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
811052a479ca718756af72f96e127f8256499ab68f76glennrp    }
811152a479ca718756af72f96e127f8256499ab68f76glennrp
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
8117cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8118cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
81190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
8122cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
81230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
81290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
8137cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8150cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8152da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
8153b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8154b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8155b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
81642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
81692b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
81742b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81754e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
81764e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
81772b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
81830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
81870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
81930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8197e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8199e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8201e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82038640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82058640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82078640fb5e9b1094f35f8beab436f81661b8a99448glennrp
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
82095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
8210dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
821126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
821326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
821426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
8219dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8220dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
82233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8224dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8225823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
8226823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->x_resolution+0.5)/2.54);
8227823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
8228823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->y_resolution+0.5)/2.54);
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8230dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8233dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8234823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution+0.5);
8235823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution+0.5);
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8237991d11dd9c33e65872778b81aff1347cd2878154glennrp
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8240dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
8241dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
8242dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8244991d11dd9c33e65872778b81aff1347cd2878154glennrp
8245823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
8246823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8247823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
8248823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
8249823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
8250991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
825226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8254a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
825526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
825626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
8257a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8259a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
8260a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
8261a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
8262a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
8263a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
8264a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
82650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8266a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
8267a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
82680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8269a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
8270a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
82710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8272a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
8273a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
82740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8275a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
8276a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
82770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8278a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
8279a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
82800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8281a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
8282a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
82830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
82840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
82863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
82873b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82883b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
82893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
82903b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82913b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
82923b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
82930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
829526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
83020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83031273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8306fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
83070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
83080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
83108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
83118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
83120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
83140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
83150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
83160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
83170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
83190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
8321f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
83220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
83240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
83250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
83260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
83270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
83280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
83290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
83310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
83330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
83382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
83408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
83418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
83425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
834358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
83448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
83450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
83460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
83470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
83480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
83498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
83528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
83530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83552cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
83568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
83570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
83590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
83600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
83638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
83640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83651273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
83664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
83671273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
83681273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
83691273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
83701273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
83714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
83724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
83734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
83740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
83764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
83780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
83825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
83885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
83940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
83980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
84005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
84013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
84022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
84038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
84048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
84057c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
84067c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
84077c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84087c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84117c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84153c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
84160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8417d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
84188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
84190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8420d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8426d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
84273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
84335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
84345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
84355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84367c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
84377c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
84387c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84405aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
84418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
84425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
84455aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84465aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84480b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84495aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
84515aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84525aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
84545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
84555aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
84565aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84575aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
84595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
84620b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
84655aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84665aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84675aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
84680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
84695aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
847326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84748640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
847526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
84765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
84770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
84780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
84790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
84800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
84810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
84820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8484d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
8485d6bf1617e99df0272b231855a933a74e99b6578fglennrp
84865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84888d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
84898d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84918640fb5e9b1094f35f8beab436f81661b8a99448glennrp
84925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
849435ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
84955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
84960f111984738842d27d04aed2a3f823d82a943506glennrp
84970f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
84980f111984738842d27d04aed2a3f823d82a943506glennrp           {
84990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
8500c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              (void) ThrowMagickException(&image->exception,
85010f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
8502c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                "image has 0 colors", "`%s'","");
85030f111984738842d27d04aed2a3f823d82a943506glennrp           }
85040f111984738842d27d04aed2a3f823d82a943506glennrp
850535ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
85065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
8507d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8509d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
8510d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
8511d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8512d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
85130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8514d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8515d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
8516d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
85170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8518d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
8519d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
85225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
85232b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8527e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
85280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8530e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
85310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8533e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
85340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85363c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
85378640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
85388640fb5e9b1094f35f8beab436f81661b8a99448glennrp
85398640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8540e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
854358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
85464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
85477c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
85487c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
85497c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
85502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85517c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
85527c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
85537c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
85542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
85564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
85584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
85594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
85614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
85624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
8563a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
85644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
85657c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
85667c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
85677c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
85684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
85714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
85731273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp                mask;
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
85760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
85784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
85790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
85814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
85820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
85844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
85850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
85874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
85880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
85904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
85910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
85934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
85940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
85964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
85970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
85994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
86004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
86010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
86030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
86054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
86060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
86084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
86094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
8610fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
8611fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
8612fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
8613fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
8614fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
86154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
86162b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
86184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
86197c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
86207c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
86210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
86234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
86244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
86254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
86264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
86274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
86284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
86294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
86304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
86314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
86324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
86355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
86365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
86375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
86385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86428640fb5e9b1094f35f8beab436f81661b8a99448glennrp
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
86440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86452e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
86470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
864839992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
86508d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
86518d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
865335ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
86540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
86569c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
86570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86587c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
86614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
86634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
86644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
86654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
86664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
86684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
86694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
86704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
86750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8676272f23a9dfc9a9104b8cd180c97afba2d20c6683cristy        if ((image_colors == 0) || ((ssize_t) image_colors-1 > MaxColormapSize))
8677f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
86780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
86805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
86810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
86855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
86895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
86900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
869135ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
8692bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
86935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
86980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
87021a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
87194bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
87249c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
87250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
87279c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
87280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
87309c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87332b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
87345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
87380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
874117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
874217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
87485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
87490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
875058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87529c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
87530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87559c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87569c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8761bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87683b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
877098156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
8771f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
87720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
877339992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8777d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8779befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8780befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8781befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
87825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8783befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
87840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8785befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
87865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
87900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
879158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
87920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
87930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8794d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8795d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
87960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8798d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8799d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
88020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
88030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8804d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
88050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8806c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8807c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8808c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8809c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8810c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8811d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8812d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8813d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8814d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8815d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8816d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8817d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
88180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
88190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8825c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
88280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
88324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
88334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
88354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
88405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
88415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
88425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
88435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
88444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
88454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
88464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
88474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
88494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88564383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
88574383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
88582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
88625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
886835ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
886935ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
887035ef824baa82511126ff0072ae30eee0da9c05a3cristy
887122ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
887426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8876a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
88803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
88823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8883991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
888426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
88875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
888917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
889026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
889126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
88921273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
889317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
889417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
889517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
889617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
889717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
889817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
889917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8900a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8901a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
890217a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
890317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
890417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
890517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
89063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
89070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
89080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
89100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8911a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
891213d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8913a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
89140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
89153b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
89163b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
89170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
89180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
89200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
89210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
89220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
89230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8924a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
892517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8926d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
89273c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
89283b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
89293b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89303b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
89313c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
89323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
893317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
893426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
893517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
89440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
89460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
89490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
89500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
89520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
89560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
89580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
89610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8967bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
89680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
89720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
89810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89892b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
89960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90052b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
90118640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
90120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90138640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
90148640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
90160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90178640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
90188640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
90195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
90218640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
90220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90238640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
90248640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
90250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90352b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9039823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if ((ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse) &&
9040823b55c200d7fc1818ab539b036a9c24feaecda8glennrp     (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
9041c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
9042c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
9043c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9045c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
90460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9047c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
9048c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
9049c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
9050c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
9051c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
905226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
9053c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
9054c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
9055c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
9056c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
9057e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
9058c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
9059e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
9060e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
9061e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
9062c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
9063c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
906426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
90650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9066c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9068c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
9069c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
9070cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
9071c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
9072c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
9073c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
9074c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
9075c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
90760b206f5daa453dc1035db5890cabc899736dc2d0glennrp
9077c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
9078c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9079c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
90800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9081c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
9082c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
909026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
909126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
909226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
909326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
909426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
909526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
909626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
909726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
90980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
909926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
9100cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
9101cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
91020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
910326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
910426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
910526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
910726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
91085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91112cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
91122cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
911326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
911426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
91243b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
912726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
91282b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
912926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
913126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
913226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
913326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
913426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
913526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
913626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
913726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
913826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
913926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
914026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
914126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
914226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
914326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
914426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
914526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
914626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
914726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
914826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
914926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
915026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
915126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
915226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
915326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
915426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
915526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
915626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9158dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
91595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9166d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
91698d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
91715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
91722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
91735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
91745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
91760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
91788d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
91830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
91845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
91865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
9187991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
91880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
91930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
91940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
91960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
91970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
92035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
92050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
92115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92153bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
921958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
92240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9225b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
9226b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9227b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92300e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
9231e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
9232991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
9233c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
9234991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
9235c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
9236c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9237c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
9238c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
9239e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
9240e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
92465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
92475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
92485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
92495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
925039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
925139992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
9252f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
92530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
925539992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
92568640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
92570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
9258d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
92590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9260d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
9261d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
9265d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
92670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
92680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9269d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
92700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
92710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
92740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
927539992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
927639992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
927739992b4dd9b12ef752d55b8e402c069698851f72glennrp
927826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
927926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
928026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
928126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
928226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
9283991d11dd9c33e65872778b81aff1347cd2878154glennrp
928426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
9285dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
928626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
928726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
928826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
928926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
929026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
929126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
9292823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
9293823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
9294823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
9295823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9296823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
9297823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9298823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
9299823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
9300823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9301823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
9302823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
9303823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9304823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
9305823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
9306823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
930726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9308dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9309dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9310dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
93114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
9312dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
931326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
931426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
931526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
931626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
9317dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
931826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
931926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
932026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
932126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
932226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9323dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9324dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
9325dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9326da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
9327da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
9328da8f3a7bfddac2680a3069a490db541e7944edafglennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
9329da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
9330da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
9331da8f3a7bfddac2680a3069a490db541e7944edafglennrp
9332da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
9333da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
9334da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
9336991d11dd9c33e65872778b81aff1347cd2878154glennrp
933739992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
9338991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
93393b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
93400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
93430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
9344991d11dd9c33e65872778b81aff1347cd2878154glennrp
93450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
93460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
93470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
93480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
93490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
9350991d11dd9c33e65872778b81aff1347cd2878154glennrp
93510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
93520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
93540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
93550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
93560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
93570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93583b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
93590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
93600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9361c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
93620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
93630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
93640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
93650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
93660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
93670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
9368991d11dd9c33e65872778b81aff1347cd2878154glennrp
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
9370cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
9371da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
9373991d11dd9c33e65872778b81aff1347cd2878154glennrp
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
9375cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
937726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
93804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
938126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
938226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
938326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
938426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
938526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
938626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
938703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
938826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
938926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
939026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
939126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
939226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
939326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
93979c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
93999c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
9408b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
9409b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
94107202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9412b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
9414b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9416b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
9417b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
9418b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9420b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
9422b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9424b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
9425b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94273b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
94283b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9430b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9431b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
94320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9433b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9434e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9436cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
9437cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
94380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9439cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
9457cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
9458cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9460cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9462da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
9463b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
9464b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
9465b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9468ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
9469ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
9470ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
94748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
94768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
94778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
94798d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
94808d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
94850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
94953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94963b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
9497a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
94990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
95020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9506cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,GrayQuantum,ping_pixels,&image->exception);
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
95113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
9512bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
9513cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
95170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
95193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
95203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9521cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,RedQuantum,ping_pixels,&image->exception);
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
95230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
9525bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
9526cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
95280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95293b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
9530b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9531b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
95320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9533cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
954858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
95495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
95508d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
95540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
95612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
95678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9569cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,GrayQuantum,ping_pixels,&image->exception);
95702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9573cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RedQuantum,ping_pixels,&image->exception);
95742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
95768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
9581b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
95823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9583b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
95852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9587cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
9588b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
95892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95903b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
9591b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
95932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9594cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
95988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
95998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
96008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
96018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
96028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
96048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
96050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
96098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
96100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
96148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
96158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
96168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
96178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
9618b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
96198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
96208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
96212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
96238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
96268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
96288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9629cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,RedQuantum,ping_pixels,&image->exception);
96302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
96328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9633cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,GrayQuantum,ping_pixels,&image->exception);
96348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9639cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
96408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
96412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
96438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
96458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
96488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9649cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBAQuantum,ping_pixels,&image->exception);
96502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
96528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9653cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBQuantum,ping_pixels,&image->exception);
96542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96553b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9656b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
96582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9659cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
9660b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
96618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
96658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
96668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
96678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
96688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
96698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
96708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
96728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
96742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
96768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
96778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
96808640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
96818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
96828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
96842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9685770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
9686770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                   &image->exception);
96872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
96898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
969244757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
96934bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
96944bf89731a90c6e03598950223e19e7be7b95d630glennrp
969544757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9696cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                       quantum_info,GrayQuantum,ping_pixels,&image->exception);
969744757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
96982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
97008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
97018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
97028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
97042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9706cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
9707d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
97088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
97092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
97118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
9712179d075d718a6da568c3600b7e6b159b8a293b41glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
97135eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      quantum_info,IndexQuantum,ping_pixels,&image->exception);
97142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97155eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
97165eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
97175eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97181a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
97195eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
97205eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97215eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
97225eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
97235eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
97248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
9725cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
97268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
97278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
97282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
97308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
97318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
97328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
97338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
97348640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
97388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9739b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
9740b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9745b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
97460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9748e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
97490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9751e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
97520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
97573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
97610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
97700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
97733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
97753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
97763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9777823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
977926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
978026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
978126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
978226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
978326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
978426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
97852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
978626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
9787823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (ping_exclude_pHYs != MagickFalse       ||
9788147bc91f6859c598c4f57b6a162111b2f63614d9glennrp          LocaleNCompare(property,"png:",4) != 0 ||
9789823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
9790823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"units") != 0)
979126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
9792c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
9793c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
9794c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
9795c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
9796c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
9797c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
97982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9799c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
9800c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
98012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9802c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
9803c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
98042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9805c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
980626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
9807c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
9808c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
9809c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
9810c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
981126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
98122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9813c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
9814c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
9815c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9816c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
9817c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9818c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9819c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
9820c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
9821c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9822c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
9823c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
9824c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
982526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
982626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
982726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
98293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
9831cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
98360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
98380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
98425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
98435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
985303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
98645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
98675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
98723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
9879c70af4ac292f8db9a1ab488318912894d412cb8cglennrp     (void) ThrowMagickException(&image->exception,GetMagickModule(),
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
9881c70af4ac292f8db9a1ab488318912894d412cb8cglennrp       "`%s'",image->filename);
98820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9889cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9892cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9895da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (ping_have_blob != MagickFalse)
9896b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9897b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9898b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9899b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9900b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9901b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9902b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9903b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9904b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9905b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9906b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
99100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99495a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
99505a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
99535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
99545a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
9955e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
9956e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               3-3-3-1, or  3-3-2-1 palette.
9957e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
9958e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
9959e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
99605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
99615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
99635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
99645a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
99655a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
99695a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
99705a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
99715a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
99725a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
99735a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
99780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
99795a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
99805a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9985bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9986bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9987bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100055a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
100065a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
100075a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
100085a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
100125a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
100135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%   or transparency limitations.
100143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
100253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
10030bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
10031bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
10036bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10038bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
100393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
100410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
10042d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
100430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
100440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
100450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
10046cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
100470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
10048d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
10049d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
10050d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
10051d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
10052d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
10053d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
10054d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
100550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1006221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1006321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1006421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
100713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1007421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
100755c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
100765c7cf4e469a4dad7e277783749155932252c52dfglennrp
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
100793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
100843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10085fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1009073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
100910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
10100a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
101023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
101083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
101103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101119c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
101129c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101139c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
101173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101189c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
101199c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101209c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101229c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
101239c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
101240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101259c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
101269c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
101270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101289c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101339c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
101349c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101359c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101379c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
101389c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
101390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101409c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
101419c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
101420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101439c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
101443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
101478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
101483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
101519c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
101520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101549c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
101550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101579c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
101580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
101609c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
101610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
101639c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
101640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10165bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10166bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10167bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10168bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
10169bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10170bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101729c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10173bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
101770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
101829c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
101830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101859c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
101860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
101889c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
101890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101919c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
101920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
101949c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
101950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10196bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10197bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10198bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10199bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
10200bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10201bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
102039c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10204d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
102080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102090dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
102100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
102110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
102130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
102140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
102150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
102160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
102170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
102190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
102210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
102220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
102230dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
102240dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
102250dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
102260dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * appear in the "include-chunk" list.
102270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
102290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
102300e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
102310e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
102330e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
102340e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
102350e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
102370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
102380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
102400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
102410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
102420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1024326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1024426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
1024526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1024626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1024726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1024826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1024926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1025026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1025126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1025226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
10253a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1025426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1025526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1025626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1025726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1025803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1025903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
102605c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
102615c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
102625c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10263acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102645c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
10265acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10266acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10267acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
10268acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
102695c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10270acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102715c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1027226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10273acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10274acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
10275acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10276acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1027703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1027803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1027926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1028003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1028103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1028226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1028303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1028426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1028503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
102862cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
102872cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
102882cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102892cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
102902cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
102912cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102922cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
102932cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1029403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1029503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1029603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1029703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1029803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1029903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1030003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1030103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1030203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1030303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
1030403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1030503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1030603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1030703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1030803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1030903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1031003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1031103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
10312a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1031303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1031403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1031503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1031603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1031703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
103182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1031903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1032003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1032103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1032203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
1032303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1032403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1032503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1032603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1032703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1032803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1032903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1033003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
10331a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1033203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1033303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1033403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1033503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
103362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1033803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
103392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1034103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
103422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1034403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
103452cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1034703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1035003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
103512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1035303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1035403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1035503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
103562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1035803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1036003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1036103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
103622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1036303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1036403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
103652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10366a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10367a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
103682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1036903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1037003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
103712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10372a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10373a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
10374a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1037503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1037603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
103772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1037803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1037903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
103802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1038103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1038203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
103832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1038403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10385ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1038626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1038726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
103885c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
103895c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
103905c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10391acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103925c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
10393acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10394acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10395acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
10396acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
103975c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10398acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103995c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1040026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10401acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10402acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
10403acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10404acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1040503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1040603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1040703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1040803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1040926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1041003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1041126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1041203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
104132cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
104142cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
104152cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104162cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
104172cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
104182cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104192cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
104202cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1042103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1042203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1042303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1042403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1042503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1042603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1042703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1042803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1042903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
1043003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1043103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1043203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1043303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1043403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1043503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1043603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1043703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
10438a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1043903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1044003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1044103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1044203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1044303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1044503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1044603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1044703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1044803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
1044903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1045003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1045103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1045203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1045303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1045403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1045503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1045603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
10457a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1045803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1045903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1046003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1046103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1046403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
104652cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1046703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
104682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1047003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
104712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1047303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1047603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
104772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1047903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1048003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1048103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
104822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1048303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1048403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1048603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1048703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
104882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1048903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1049003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
104912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10492a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10493a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
104942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1049503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1049603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
104972cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10498a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10499a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
10500a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1050103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1050203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
105032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1050403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1050503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
105062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1050703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1050803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
105092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1051003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10511ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1051226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1051326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1051403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1051526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1051626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
1051826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1051926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1052126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1052226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
1052426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1052526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1052726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1052826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1053026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1053126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1053326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1053426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1053526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1053726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1053826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1053926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1054126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1054226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1054426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1054526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1054726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1054826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
10550a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
10551a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10552a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1055326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1055426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1055626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1055726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1055926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1056026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1056126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1056226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1056326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10564b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10566b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
105690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
105720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1058903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
105963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
105993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10606bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
106083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
10610fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
106350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
106400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
106420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
106490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
106510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
106573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
106590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
106620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
106650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
10721f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
107230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10726e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
10727e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1073903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
107404e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
107414e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10755f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
107560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10758f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
107590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
107620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
107650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
107680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
107710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
107740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
107770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
107800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
10786cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
10810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1081203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1083303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
108340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10836e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10837cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10838e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
108390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10841e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10842cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10843e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
108440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1085703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1085835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1087403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1087635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1087735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1087935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1088035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1088235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1088335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1088535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1088635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1089903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1090235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
109040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1090535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
109070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
109133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1091535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
109163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
109170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1091835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
109200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1092635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1092735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1094203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10943bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10944bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1095303812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10969bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10975e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10976f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
109793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10981bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
109850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10989bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1099003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
109933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11000e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
11001e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
110093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11011e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
11012bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1101403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11050e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
11051e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
110550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
110630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
110650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11069e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
11070e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
110713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11073e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
11077bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1107903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
11090cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1109503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
111020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
111353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1113721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1113803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
111493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
111503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11152fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1116173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
111723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
111813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
111873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
111893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1119521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1119803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1119903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1120003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11218bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11228bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11235d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
112473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11249fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
112523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
112563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1125873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
112613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
112633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
112653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
112713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
112723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
112783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
112833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
112990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11301e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
113020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11310e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
113110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11313e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
113140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
113180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
113220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
113243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
113260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
113300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11333e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
113340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
113380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
113463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
113473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
113513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
113523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
113583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
113663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
113673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
113683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
113703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
113753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
113763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
113773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
114010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
114073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
114080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
114110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
114163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
114170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
114200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
114220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
114260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
114283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
114323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
114333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
114340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
114383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
114393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
114403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
114423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
114433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
114453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
114463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
114483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
114513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
114523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
114540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
114570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
114610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
114660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
114723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
114733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
114913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
115040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
115083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
115093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
115103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
115113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
115123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
115143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
115153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
115163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
115173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
115180261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
11519d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
11520d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
11521d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
11522d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
11523d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
11524d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
11525d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
115273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
115293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
11531cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
11532cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
115333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
115343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
115350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
115380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
115403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
115410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
115463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
115473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
115503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
115513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
115533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
115543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
115553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
115583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
115603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
115613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1156203812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
115634e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
115644e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
115653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
115663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
115673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
115693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
115750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
115840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
115873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
115960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
115993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
116050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
116123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
116133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
116143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
116223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
11623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1162403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
116283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
116303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
116313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
116323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
116373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1163803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
116393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
116403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
116413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
116423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
116430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
116453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
116460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
116483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
116490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
116513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11653e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
11654e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
116550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
116573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11658e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
116590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11662e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
116683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
116693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
116703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
116713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
116723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
116753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
116773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1167803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
116790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
11681e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11682cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11683e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
116840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
11686e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11687cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11688cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
116890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
116913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
116923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
116983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
117003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
117013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
117023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
117033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1170403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1170535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
117063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
117073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
117093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
117113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
117133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
117143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
117173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
117183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
117193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1172003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
117213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1172235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1172335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
117243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1172535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1172635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
117273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1172835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1172935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
117303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1173135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1173235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
117333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
117343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
117353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
117363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
117393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
117413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
117423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
117433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
117443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1174503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
117460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1174935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
117503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
117510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1175235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
117540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
117563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
117593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1176235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
117633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
117640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1176535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
117670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1177335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1177435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
117803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
117833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
117843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
117853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1179303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
117973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
117993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
118003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
118013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
118023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
118033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
118043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
118053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1180603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
118073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
118143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
118163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
11817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
118183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
118193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
118223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
118243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
118253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1182603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
118270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
118293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
118303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
118323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
118333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
118340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
118363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
118393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
118423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
118433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
118483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
118493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
118503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
118563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
118573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
118583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
118593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
118603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
118623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
118653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
118663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
118673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
118683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
118693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
118703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
118743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
118763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
118773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1187803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
118790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11880bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
118813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
118833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
118843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
118860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
118893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
118963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
118983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11899bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
119043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
119073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
119093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
119123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
119143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1191903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
119223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
119333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1194803812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
119493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
119513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
119523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
119543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
119573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1196003812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
119613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
119633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
119643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
119653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
119663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
119673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
119703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
119724e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
119733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
119753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
119783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
119813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
119863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
119873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
119883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
119893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
119903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
119913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
119933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
119943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
119982f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11999b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
120002f2e514554975d510c88df54de98c6cdc1080f1cglennrp
120012f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
120022f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
120032f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
120042f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
120052f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
120062f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
120072f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
120082f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
120092f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
120102f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
120112f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
120122f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
12013a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
120142f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
120152f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
120162f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
120172f2e514554975d510c88df54de98c6cdc1080f1cglennrp
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
120203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
120243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
120263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
120293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
120313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
120323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
120330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
120353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
120360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
120380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
120403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
120433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
120473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1204803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
120493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
120503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
120513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
120543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
120563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
120570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
120593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
120600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
120623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12063d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1206439992b4dd9b12ef752d55b8e402c069698851f72glennrp
120653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
120663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
120683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
120693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
120700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
120723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
120733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1207439992b4dd9b12ef752d55b8e402c069698851f72glennrp
120753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
120763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
120783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12079d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
120803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12081