png.c revision 5961225e531a5f26ae179c1d919582d5cdaa44bb
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
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
1616fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1619cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
162225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
162861b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
162961b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
163061b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
163161b4c957269727a0a2526edc2331881da8346100glennrp    {
163261b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
163361b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
163461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
163561b4c957269727a0a2526edc2331881da8346100glennrp    }
163661b4c957269727a0a2526edc2331881da8346100glennrp#  endif
163761b4c957269727a0a2526edc2331881da8346100glennrp#endif
163861b4c957269727a0a2526edc2331881da8346100glennrp
163961b4c957269727a0a2526edc2331881da8346100glennrp
1640ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1643a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
1644a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
1645a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
1646a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
16470e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
16480e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
16490e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
16500e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
16510e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.opacity=65537;
16520e319739731741c52a6303723e0c8678a0df5579glennrp
1653cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
16544eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
1655cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
1656cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
1662cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
1663cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
1666cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
16720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
16800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1687cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
16880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1689faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1696cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17037b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
17047b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
17057b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
17067b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
17070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1713faa852bad40107edae19405e76a299057668d795glennrp
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1749991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1750991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1751991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1765991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1769faa852bad40107edae19405e76a299057668d795glennrp
1770faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1771faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1772faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1773faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1774faa852bad40107edae19405e76a299057668d795glennrp
1775faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1776faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1777faa852bad40107edae19405e76a299057668d795glennrp
1778faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1779faa852bad40107edae19405e76a299057668d795glennrp
1780faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1782faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1783faa852bad40107edae19405e76a299057668d795glennrp        {
1784faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1785faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1786faa852bad40107edae19405e76a299057668d795glennrp        }
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1788faa852bad40107edae19405e76a299057668d795glennrp
1789faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1791faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1795e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1796e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
17970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1800faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
18010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1804faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
18050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1808faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1811faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1812faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1817e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
1818e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
1819e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1820e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
1821e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
1822e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1823e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
1824e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1852cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1853cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        (mng_info->global_srgb_intent);
18540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1857cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1858cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
18590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1862e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1867faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1868faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1869faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
18700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1879faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1880faa852bad40107edae19405e76a299057668d795glennrp    {
1881faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1882faa852bad40107edae19405e76a299057668d795glennrp        {
1883faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1884faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1885faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1886faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1887faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1888faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1889faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1890faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1891faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1892faa852bad40107edae19405e76a299057668d795glennrp        }
1893faa852bad40107edae19405e76a299057668d795glennrp    }
18940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1895faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1912e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1914e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1915cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
1916cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
1917faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1918faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1919faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1920faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1923faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1925905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
1926905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
19270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1931e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1932e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1936faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1937faa852bad40107edae19405e76a299057668d795glennrp    {
1938faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1939faa852bad40107edae19405e76a299057668d795glennrp        {
1940faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1941faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1942faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1943faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1944faa852bad40107edae19405e76a299057668d795glennrp        }
1945faa852bad40107edae19405e76a299057668d795glennrp    }
1946faa852bad40107edae19405e76a299057668d795glennrp
1947faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19530881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19540881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19550881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1966e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1970823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
1971faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
19800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
1982faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
19880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1989faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2006faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2015faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2016faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2039faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2040faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2043faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20522cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2054faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2055faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2056faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20592cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20612cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
20622cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
20632cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20642cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20652cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
20672cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20682cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20692cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
20700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20712cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
20722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
20730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
20752cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
20760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20772cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
20782cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
20790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20802cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
20812cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
20822cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20832cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
20842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
20852cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
20862cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
20892cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
20910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
20942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
20962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2098faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
20990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2101faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2104faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2106f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2110e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2111e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2112e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2113e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2117a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2118faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2121a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212635ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
212735ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
212835ef824baa82511126ff0072ae30eee0da9c05a3cristy
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2133f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2135faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2136faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2137faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2138faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2139faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2140faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2146faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2151a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2152a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2153a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2154a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2155a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2156a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2157a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2158a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2159a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
2160a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.opacity= scale_to_short*ping_trans_color->gray;
216105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2162faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21640f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
21650f111984738842d27d04aed2a3f823d82a943506glennrp              {
21660f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21670f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
21680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21690f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21700f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
21710f111984738842d27d04aed2a3f823d82a943506glennrp              }
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2181faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2186faa852bad40107edae19405e76a299057668d795glennrp
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2188faa852bad40107edae19405e76a299057668d795glennrp
2189faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2190faa852bad40107edae19405e76a299057668d795glennrp
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2195bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2197bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2200faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2201faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2212faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2213faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2214faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2215faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2216faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2218befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2219befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2220befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2222befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2223befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2231faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2240bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2256faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2266bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2279faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
22800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2284bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2292147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2293cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2294cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2295147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2296147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2297147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2298147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2299147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2300147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2301147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_width);
2302147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.width           ",msg);
2303147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2304147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_height);
2305147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.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
28834eb3931feb349dd87142c78503b779228f3e1a0fglennrp  for (int 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,
30544eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "%d 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       {
30915961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) FormatMagickString(msg,MaxTextExtent,"intent=%d (See Rendering intent)",
30924eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (int) intent);
30934eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:sRGB                 ",msg);
30944eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
30954eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
30964eb3931feb349dd87142c78503b779228f3e1a0fglennrp
30974eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
30984eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
30995961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) FormatMagickString(msg,MaxTextExtent,"gamma=%.8g (See Gamma, above)",
31004eb3931feb349dd87142c78503b779228f3e1a0fglennrp            file_gamma);
31014eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:gAMA                 ",msg);
31024eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3103cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31044eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3105cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
31064eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
31074eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) FormatMagickString(msg,MaxTextExtent,"x_res=%.10g, y_res=%.10g, units=%d",
31084eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
31094eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:pHYs                 ",msg);
31104eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31114eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3112cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31134eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
31144eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
31154eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
31164eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) FormatMagickString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
31174eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
31184eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:oFFs                 ",msg);
31194eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31204eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
31214eb3931feb349dd87142c78503b779228f3e1a0fglennrp
31224eb3931feb349dd87142c78503b779228f3e1a0fglennrp     /* TO DO: vpAg */
3123cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3124cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3130cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3132cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
31380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
315121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
315221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
316947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
317347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3176fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
318047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
318347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
318847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3189dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
319147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
319673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
319747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
320047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
321147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
32180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
32260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
322947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
323147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
32370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
324047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
32440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
325047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
32590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
326197f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
326297f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
326397f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
326497f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
326597f90e23c85b9c58387880125c29d8c99126f83aglennrp
326697f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
32680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33204383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
33214383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
33224383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3323bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3346bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3361bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3375fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
33780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
33870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
33890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
33920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
34200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
34230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3431e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3432e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
34360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
343947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
34430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3447bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
34490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
345247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
345947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
347547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
347847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
348347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3487f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
348847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3490f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
349147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
349447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
349847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
350247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
350647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
351047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
351447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
351847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
352447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
352747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
354373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
354447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
354747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
35500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
35570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
35610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
356873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
35690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
35750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
35860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
35900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
35930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
36020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
36050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
360803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
362547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
363247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
363547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
364447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3652bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
365403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
366947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
36890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
37198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
37200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
37308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
37318182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
37328182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
37338182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
37348182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
37358182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
37368182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
373847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3747e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3748cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
375947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37685eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
37695eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
37700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
377747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
37898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3805fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
38180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
384747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
38510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
38540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
38570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
38710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
38750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
388147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
38870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
389803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
39020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
39040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
39130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3915bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
392047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
39240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3926bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
39320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
394447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
394547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
39530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
39550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
39560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
39590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
39610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
39650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
39720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
39760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
401821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
401921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4039fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
405047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
405147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
405347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40543b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
405747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
405847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
406073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
40610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
406547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
406647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
40740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
40820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
409047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
41020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41164383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
411721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
411821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
41194383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4126bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4151bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4157bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
418338ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
418438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
418538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4186bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
420847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
420947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4215fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
42190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
42220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
422647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
422747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
422847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
422973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
42300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
423447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
423547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
424547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
424947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
425047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4253bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4254bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
425847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4301e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4302e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
43060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
43090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
43120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
431647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
431947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
432247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
43360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
43470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
435247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
43570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
43640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4370bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4373bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
43750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4379e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4381e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
43858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
43860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
43890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
43930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
43960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
44008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
44040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
44070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
44100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
441747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
44190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
44220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4431e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4432e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4433f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
44340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4436bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4438bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
44400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
44430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
44560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44598182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
44608182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
44610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
44640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
44730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4475e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
44760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4478e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
44920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
45210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
45240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
45310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
45320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
45340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
45350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4539e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4540f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
45410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4543e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4544f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
45540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
45610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
45840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
45870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
461047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
461347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
461447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
46200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4621bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
462835ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
46370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
46430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
464747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4653bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
466012560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4668bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46718182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
46780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
468547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
468647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
46908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
46918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
46938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
46958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
46978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
46998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
47018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
470647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
471047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4718e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4719cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
472447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
472847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4731fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
473847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
474147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
47510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
475547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
47590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
47630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
476647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
476747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
476947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
477247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
477447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4775bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
478647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
47908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
47910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
47938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
47940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4795bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4796bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
47970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
48000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
48020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4805e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
480747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4810bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4811bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
48120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4813bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4814bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
48150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4816bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4817bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
48180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
48210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
48230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4826e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
482847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
48340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4838e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4839e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
484047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
48480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4849bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
48510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4852bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4860e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4861e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
48620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
486647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
487047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
487747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
49030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4907e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4908e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
492547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
493747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
496147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
496247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4971bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4974bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
498647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4989bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
499347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
499447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4997bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
501447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5021bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
502447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
502547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
50268182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
50270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5030e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5031e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
50320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
50350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
504647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
505047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
506247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
50690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5073e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5074f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
507547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
50800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
508547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
510347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
510747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
511447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
511747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
51340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
51370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
51400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
515147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
515747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
516347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
516647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
517247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
517547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
518147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
518447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
519047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
519347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
519947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
520247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
520847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
521147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
521747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
522147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
522947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
524847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
525547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
525847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
526547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
526847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
527347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
52898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
52918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
529547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
530447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
531047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
531547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
532847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
533147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
533447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
533747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
534047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
534347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
534647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
535447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
535747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
536047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
536547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
537547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
538247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
538547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
539147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
539947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
54018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5414bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5416bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
542447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
543147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
543547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
544247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
544547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
544647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
544747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5459e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5460e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
547747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
548447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
54890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
549947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
55100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5514e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5515e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
551947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
552647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
553347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
55390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
55420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
55510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
55600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
556647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
557047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
557547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
557747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
558947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
560247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
563547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
563847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
564047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
564147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
564347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56464e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
564747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
565047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
565347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
565547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
565647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
565847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
566247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
566547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
566747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
566847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
567047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56734e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
567447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
567747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
568047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
568247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
568347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
568547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5695bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5699bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
571447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
571547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
571947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
572147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5745bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
574947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5750bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
575847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
576947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
577447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
577747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
578047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
578347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5792e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
579847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
580747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
581047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
581547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5816bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
581847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5819bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
582147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5822bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
582447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
582747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
583147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5832bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
583847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5844bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
585047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5851bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5853fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
586447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
586947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5873bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5877bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5879bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5880bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
588247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5884bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5887bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
588947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
589947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
590547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
590847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5911bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5912bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
592047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
592347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
592647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5945e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5947bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
595547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5956bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5959bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5960bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
596147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5962bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5963bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
596447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5965bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
596747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5968bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
597047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
597347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
598147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
598647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5992bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5995bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5998bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
6001bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
600447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
601447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
602047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
602347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
6028bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
603747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6047bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
605047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6051bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
605947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
609347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6109bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6110bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
611647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
612847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
61522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
61532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
61542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
61552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
61562b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
61572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
61582b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
61590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
61608640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
61618640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6163d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
616547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6169bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6172d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6176d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
617847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
618047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
618447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
61950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
620647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
621047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
62230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
62260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
62310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
624247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
624647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
62510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
625647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
626247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
627047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
627547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
628147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
628447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
628747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
62950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
63010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
630647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
63120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
63140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6317e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6318e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
63190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
632747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
633047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6332e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
633347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6338e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6350bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
635547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
635847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
636147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
636447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
637347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
637647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
639347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
640347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
640647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6408e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6409e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
641047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6412f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6413f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
641447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6415f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6416e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6417e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6418f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6419f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
642047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
642447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
642747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
643025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
643547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
643847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
644147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
644625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
648547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
649147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
649947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
650347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
651147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
651447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
651947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
652247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
652547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
653147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
653647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
654147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
654447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
654947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
655447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
656447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
656847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
657547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
657847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
658347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
659147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
659647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
660447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
661147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
661847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
661918b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6620cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
662118b17443128598500357da7bff2f01683cf32890cristy#endif
662247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
665347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6655cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
6656cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
666125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
6737cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6744bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
67650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
67660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
67680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6787f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
678947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
679747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
680447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
680747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6813cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
68144383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
682847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
682947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
683047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
683247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
6836cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
683847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
683947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
684047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
684147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
684247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
684347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6844cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
6845cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
6846cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
684747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
684847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
684947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
685047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
685147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
685247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
685347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
6854cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
685547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
685747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
686047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6864b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6865b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6867b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6869b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6870b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6871b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6872b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6873b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6874b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6888cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6889cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6890e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6891e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
68925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
689339992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
689439992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
68975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
68985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
68995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
69075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
69085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
69095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6910bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
691458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
691521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
691658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
691758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
6918da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
6919fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
6920d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
69218d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
692239992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6923991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6924991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6925991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
692626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
692726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
692826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
6929e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
693026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
693126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
693226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
693326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
693426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
693526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
693626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6937e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
693826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
693926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
694026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
694126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
69420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
69430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
694482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
6945d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
6946d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6951bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6956cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
6959f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
69600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
69615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
69625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
69635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
69645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
69655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
69665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6967bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
69685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
69695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6971bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6976dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6977fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
6978f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
69798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
69808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
69818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6982dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6983dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6984dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6985dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6986dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6987dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
6989fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6991b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
6992b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
6993b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6995cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
69990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
70005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
70015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
70025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
70035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
70045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
70055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
70065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
70075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
70085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
70095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
70105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
70115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
70125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
70135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
70145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
70155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
70165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7017dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7018dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7019dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7020dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7021da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7022d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
70238d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
702439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7025991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7026991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7027991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7028991d11dd9c33e65872778b81aff1347cd2878154glennrp
70290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
70300e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7031dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
70320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
70330e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
70340e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
70350e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
70360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
70370e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
70380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
70390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7040dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
70410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
70420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
70430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
70440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
70460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
70488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
70498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
70508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7051fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7052fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7053fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7054fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7055fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7056fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7057fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7058fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7059fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7060fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7061fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7062fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
7063fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
70660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70673241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
70683241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
70693241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
70703241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
70713241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
70723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
70733241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7074a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7075a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7076a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7077a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7078a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7079a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7080a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7081a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7082a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7083a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7084a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7085a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
70862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70872b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
70882b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
70892b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
70902b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
70912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
70922b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
70932b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
70948640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
7095c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
70968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
70978640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
70988640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
70998640fb5e9b1094f35f8beab436f81661b8a99448glennrp
7100c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
7101e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
7102e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
7103e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * RGBA palette and run again, and finally to a simple 3-3-2-1 RGBA
7104e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * palette.  The final reduction can only fail if there are still 256
7105e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * colors present and one of them has both transparent and opaque instances.
7106c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
710782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
710882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
7109d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
711082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
7111d337164012450d70d62e71cf4a308a29004f7d57glennrp  for (j=0; j<5; j++)
7112d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
7113d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
7114d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7115d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
7116d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
7117d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7118d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
7119d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
7120d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
7121d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
7122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
7123d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7124d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * If image->matte is MagickFalse, we ignore the opacity channel
7125d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
7126d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7127d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
7128d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
7129d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
7130d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7131d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
7132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
7133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
71343c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
713552a479ca718756af72f96e127f8256499ab68f76glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
713652a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 0 /* Shift */
713752a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 1 /* Scale */
713852a479ca718756af72f96e127f8256499ab68f76glennrp#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
713952a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 8
714052a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 0x0101
714152a479ca718756af72f96e127f8256499ab68f76glennrp#else
714252a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 24
714352a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 0x01010101
714452a479ca718756af72f96e127f8256499ab68f76glennrp#endif
714552a479ca718756af72f96e127f8256499ab68f76glennrp
7146d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   ExceptionInfo
7147d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *exception;
71488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7149d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
7150d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
71518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7152d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   PixelPacket
7153d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
7154d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
7155d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
71568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7157d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register IndexPacket
7158d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *indexes;
71598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7160d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register const PixelPacket
7161d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *s,
7162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *q;
7163d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7164fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   register PixelPacket
7165fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
7166fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
7170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7172d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7173d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7174d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
7175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7176d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
7177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
717903812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
71813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7182fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
71837ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
71847ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7185d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
71868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "        i    (red,green,blue,opacity)");
71882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7189d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
71907ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
7191d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7192d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7193d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7194d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7196d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7197d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
71987ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
71992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7200d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
7201d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7202d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
7203d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7204d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7205d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7207d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7208d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
7211d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7212d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
7213d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
72142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
721783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7218d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
7219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7220d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "        (zero means unknown)");
72217ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      Regenerate the colormap");
7224d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
72257ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7226d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     exception=(&image->exception);
7227d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7228d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
7229fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
7230fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
7231fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
72322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
7234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7235d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
72367ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7237d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (q == (PixelPacket *) NULL)
7238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
723997fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
7240d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
7241d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7242d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (image->matte == MagickFalse || q->opacity == OpaqueOpacity)
72438d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
72458d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
7247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0]=*q;
7249d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0].opacity=OpaqueOpacity;
7250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
7251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
7254d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7255d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(opaque+i, (PixelPacket *) q))
7256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7259d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_opaque &&
7260d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque < 259)
7261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
7263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i] = *q;
7264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i].opacity = OpaqueOpacity;
7265d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
72668d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
72678d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (q->opacity == TransparentOpacity)
72698d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7270d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
72718d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
7273d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7274d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[0]=*q;
7275d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.red=(unsigned short)(q->red);
7276d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.green=(unsigned short) (q->green);
7277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.blue=(unsigned short) (q->blue);
7278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.gray=(unsigned short) (q->blue);
7279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
7280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7281d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
7283d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(transparent+i, (PixelPacket *) q))
7285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7288d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
7289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
7290d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
7292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[i] = *q;
7293d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
72948d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
72958d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7297d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7298d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
7299d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7300d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
7301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[0]=*q;
7303d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
7304d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
73058d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7306d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
7307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(semitransparent+i,
7309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          (PixelPacket *) q) &&
7310d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          q->opacity == semitransparent[i].opacity)
7311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7313d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7314d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
7315d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
7316d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7317d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
7318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[i] = *q;
7319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7320d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
73218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
7322d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           q++;
7323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
7324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
73253c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (ping_exclude_bKGD == MagickFalse)
7327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7328d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
7329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
7330d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7331d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
7332d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7333a080bc32a4a8b2ffec83fd836a28753959175363glennrp             if (IsColorEqual(opaque+i, &image->background_color))
7334d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             break;
7335d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7336a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
733803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
7339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i]=image->background_color;
7340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i].opacity = OpaqueOpacity;
7341d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               number_opaque++;
734203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
7343a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
7344a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7345a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
7346d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7348d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
73493241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7350a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
7351a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
7352a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
7353a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
7354a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
7355a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
7356a080bc32a4a8b2ffec83fd836a28753959175363glennrp
7357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7359d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
7360d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7361d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
73623241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7363d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
7364d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7365d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
7366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73673241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7368fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
7369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
7371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
73723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7373d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
7374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7375d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
7376d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7377d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
73786185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (q == (PixelPacket *) NULL)
7380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
73816185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7382d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
7383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
7384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
73856185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7386d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_color == MagickFalse)
7387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7388d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7389d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
7390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   {
7391d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != s->green || s->red != s->blue)
7392d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7393d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_color=MagickTrue;
7394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_non_bw=MagickTrue;
7395d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          break;
7396d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7397d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7398d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
74003241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
7402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
74056185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
7406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != 0 && s->red != QuantumRange)
7407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
7409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7410d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
7413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           }
7415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
74164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
7417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
7418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         PixelPacket
7420d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
7421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
7423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
7424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7425d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
7427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
7429d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
7431d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
74333241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
7435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
74363241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
7438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
7439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
7441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
7442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
7445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
7446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7447d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
7448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
7450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
7452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
7453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
7454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
7455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
7456d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
7457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
7458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
7463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
7464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
74663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
7468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
7469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
7470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
7471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
7472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7473d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
74746185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
7475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
7476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
7478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
74792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
7482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
7485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (AcquireImageColormap(image,image_colors) ==
7487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
7488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               ThrowWriterException(ResourceLimitError,
7489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "MemoryAllocationFailed");
7490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
7492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
7493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
7495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
7498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
7499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
7502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7504fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
7505fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
7507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
7508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              q=GetAuthenticPixels(image,0,y,image->columns,1,
7509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  exception);
75103c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (q == (PixelPacket *) NULL)
7512d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
75133c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7514d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              indexes=GetAuthenticIndexQueue(image);
7515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7516d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
7517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7518d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
751903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
7520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
7521d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      image->colormap[i].opacity == q->opacity) &&
7522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (IsColorEqual(&image->colormap[i],
7523d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         (PixelPacket *) q)))
75246185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
7525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    indexes[x]=(IndexPacket) i;
7526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
75276185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
752803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
7529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                q++;
7530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7531d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
7533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
7534d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
7535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
7537d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
7542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
7544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 "       i     (red,green,blue,opacity)");
754783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
7549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
755072988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
7551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
7554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
7555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
7556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
7557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
7558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].opacity);
7559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
75606185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
75616185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
75623c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
7564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
7566d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
7567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
75683c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7569d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7570d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
75713c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7572d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
7573d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
7575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
757603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
7577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
75806185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
7582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7583d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
7584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
75856185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7587d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
7589a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7590d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7592d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
7593a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
7595d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7596d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
7597d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7599d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
76016185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
760203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
760303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
7604d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
76053c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7606c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
7607c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7608fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7609c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
7610c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
7611c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
7612c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
7613c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
7614c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7615fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7616c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
7617c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     * opacity to 0 or OpaqueOpacity
7618c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7619c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (number_semitransparent != 0)
7620c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7621c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7622c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
7623fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7624c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
7625c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7626c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          r=GetAuthenticPixels(image,0,y,image->columns,1,
7627c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              exception);
7628fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7629c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (r == (PixelPacket *) NULL)
7630c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
7631fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7632c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
7633c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
763482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r->opacity = r->opacity > TransparentOpacity/2 ?
763582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                   TransparentOpacity : OpaqueOpacity;
7636c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              r++;
7637c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7638c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7639c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
7640c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
7641fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7642c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
7643c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
7644c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
7645c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                image->colormap[i].opacity =
764682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    image->colormap[i].opacity > TransparentOpacity/2 ?
764782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    TransparentOpacity : OpaqueOpacity;
7648c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7649c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7650c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7651c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7652c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
7653e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
7654e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
7655e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
7656c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7657d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
7658d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
7659d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7660d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7661d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
7662d337164012450d70d62e71cf4a308a29004f7d57glennrp
7663d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
7664d337164012450d70d62e71cf4a308a29004f7d57glennrp
7665d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.red=
7666d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7667d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.red) >> PNGK) & 0xf0)     )  |
7668d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7669d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7670d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.green=
7671d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7672d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.green) >> PNGK) & 0xf0)     )  |
7673d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7674d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7675d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.blue=
7676d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7677d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.blue) >> PNGK) & 0xf0)     )  |
7678d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7679d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7680d337164012450d70d62e71cf4a308a29004f7d57glennrp
7681d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7682d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7683d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
7684d337164012450d70d62e71cf4a308a29004f7d57glennrp
7685d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
7686d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7687d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
7688d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7689d337164012450d70d62e71cf4a308a29004f7d57glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7690d337164012450d70d62e71cf4a308a29004f7d57glennrp                exception);
7691d337164012450d70d62e71cf4a308a29004f7d57glennrp
7692d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (r == (PixelPacket *) NULL)
7693d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
7694d337164012450d70d62e71cf4a308a29004f7d57glennrp
7695d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
7696d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
7697d337164012450d70d62e71cf4a308a29004f7d57glennrp              if (r->opacity == TransparentOpacity)
7698d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7699d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red = image->background_color.red;
7700d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green = image->background_color.green;
7701d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue = image->background_color.blue;
7702d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7703d337164012450d70d62e71cf4a308a29004f7d57glennrp              else
7704d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7705d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red=
7706d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->red) >> PNGK) & 0xf0)    )  |
7707d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7708d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green=
7709d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->green) >> PNGK) & 0xf0)    )  |
7710d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7711d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue=
7712d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xf0)    )  |
7713d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7714d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7715d337164012450d70d62e71cf4a308a29004f7d57glennrp              r++;
7716d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
7717d337164012450d70d62e71cf4a308a29004f7d57glennrp
7718d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7719d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
7720d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7721d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7722d337164012450d70d62e71cf4a308a29004f7d57glennrp
7723d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
7724d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
7725d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7726d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
7727d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7728d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
7729d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
7730d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7731d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].red=
7732d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7733d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].red) >> PNGK) & 0xf0)     )  |
7734d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7735d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7736d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].green=
7737d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7738d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].green) >> PNGK) & 0xf0)     )  |
7739d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7740d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7741d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].blue=
7742d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7743d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].blue) >> PNGK) & 0xf0)     )  |
7744d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7745d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7746d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7747d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7748d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
7749d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
7750d337164012450d70d62e71cf4a308a29004f7d57glennrp
775182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
775282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
775382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
775482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
775582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
775682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
775782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
775882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
775982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.red=
776082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
776182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xe0)     )  |
776282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
776382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xe0) >> 3)  |
776482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
776582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xc0) >> 6)) * PNGM;
776682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.green=
776782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
776882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xe0)     )  |
776982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
777082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xe0) >> 3)  |
777182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
777282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xc0) >> 6)) * PNGM;
777382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.blue=
777482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
777582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xe0)     )  |
777682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
777782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xe0) >> 3)  |
777882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
777982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
778082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
778182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
778282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7783e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
778482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
778582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
778682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
778782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
778882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
778982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
779082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                exception);
779182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
779282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (r == (PixelPacket *) NULL)
779382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
779482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
779582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
779682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
779782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
779882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
779982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
780082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
780182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
780282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
780382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
780482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
780582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red=
780682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->red) >> PNGK) & 0xe0)    )  |
780782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xe0) >> 3)  |
780882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xc0) >> 6)) * PNGM;
780982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green=
781082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->green) >> PNGK) & 0xe0)    )  |
781182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xe0) >> 3)  |
781282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xc0) >> 6)) * PNGM;
781382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue=
781482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xe0)    )  |
781582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xe0) >> 3)  |
781682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
781782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
781882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r++;
781982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
782082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
782182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
782282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
782382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
782482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
782582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
782682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
782782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
782882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
782982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
783082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7831e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
783282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
783382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
783482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].red=
783582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
783682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xe0)     )  |
783782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
783882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xe0) >> 3)  |
783982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
784082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xc0) >> 6)) * PNGM;
784182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].green=
784282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
784382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xe0)     )  |
784482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
784582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xe0) >> 3)  |
784682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
784782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xc0) >> 6)) * PNGM;
784882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].blue=
784982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
785082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xe0)     )  |
785182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
785282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xe0) >> 3)  |
785382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
785482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
785582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
7856d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7857d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
785882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
7859c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7860c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors == 0 || image_colors > 256)
7861c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7862c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7863c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7864c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
7865c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7866c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.red=
7867770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7868770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xe0)     )  |
7869770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7870770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xe0) >> 3)  |
7871770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7872770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xc0) >> 6)) * PNGM;
7873c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.green=
7874770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7875770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xe0)     )  |
7876770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7877770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xe0) >> 3)  |
7878770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7879770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xc0) >> 6)) * PNGM;
7880c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.blue=
7881770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7882770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0)     )  |
7883770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7884770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 2)  |
7885770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7886770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 4)  |
7887770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7888770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
7889fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7890c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7891c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7892e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
7893fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7894c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
7895c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7896c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
7897c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
7898c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7899c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                exception);
79008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7901c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (r == (PixelPacket *) NULL)
7902c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
7903c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7904c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
7905c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
790682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
790782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
790882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
790982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
791082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
791182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
791282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
791382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
791482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red=
791582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->red) >> PNGK) & 0xe0)    )  |
791682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xe0) >> 3)  |
791782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xc0) >> 6)) * PNGM;
791882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green=
791982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->green) >> PNGK) & 0xe0)    )  |
792082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xe0) >> 3)  |
792182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xc0) >> 6)) * PNGM;
792282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue=
792382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xc0)    )  |
792482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 2)  |
792582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 4)  |
792682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
792782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
792852a479ca718756af72f96e127f8256499ab68f76glennrp              r++;
7929c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
7930fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7931c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7932c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
7933c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7934c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7935c722dd852e8abe407c2846d39662f7ade9c234deglennrp
7936c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
7937c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
7938c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7939c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
7940c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7941e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
7942c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
7943c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
794452a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].red=
7945770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7946770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xe0)     )  |
7947770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7948770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xe0) >> 3)  |
7949770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7950770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xc0) >> 6)) * PNGM;
795152a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].green=
7952770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7953770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xe0)     )  |
7954770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7955770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xe0) >> 3)  |
7956770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7957770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xc0) >> 6)) * PNGM;
795852a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].blue=
7959770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7960770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0)     )  |
7961770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7962770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 2)  |
7963770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7964770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 4)  |
7965770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7966770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
7967c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7968c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
7969c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7970c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7971c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
7972fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
7973fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
7974fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7975fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
7976fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
7977fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
7978fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
79790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
79800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
79810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
79820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
79830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
79850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
79860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
79880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
79890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79908d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
79918d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         mng_info->write_png_colortype != (ssize_t) colortype)
79920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
79930b206f5daa453dc1035db5890cabc899736dc2d0glennrp
79940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
79950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
7996fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
7997fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
7998fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
79995a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
80005a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
80015a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
8002fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
80035a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
80045a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
8005fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8006fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
8007fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8008fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
8009fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
8010fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8011fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
8012fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
8013fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8014fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           ExceptionInfo
8015fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *exception;
8016fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8017fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           register const PixelPacket
8018fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
8019fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8020fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           exception=(&image->exception);
8021fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8022fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8023fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8024fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8025fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8026fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (q == (PixelPacket *) NULL)
8027fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8028fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8029fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8030fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
8031fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 if (q->opacity != TransparentOpacity &&
8032fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->red == ping_trans_color.red &&
8033fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->green == ping_trans_color.green &&
8034fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->blue == ping_trans_color.blue)
8035fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8036fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8037fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8038fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8039fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8040fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 q++;
8041fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8042fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8043fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8044fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8045fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8046fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8047fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8048fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8049fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Assuming that image->colormap[0] is the one transparent color
8050fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             * and that all others are opaque.
8051fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             */
8052fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
8053fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              for (i=1; i<image_colors; i++)
8054fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                if (image->colormap[i].red == image->colormap[0].red &&
8055fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].green == image->colormap[0].green &&
8056fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].blue == image->colormap[0].blue)
8057fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
8058fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8059fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8060fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8061fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8062fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8063fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8064fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8065fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8066fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8067fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8068fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8069fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8070fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8071fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8072fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8073fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8074fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8075fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8076fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
80773c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
80783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
80793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
80803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8081f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
80823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
808383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
80840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
80851273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
808752a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
808852a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
808952a479ca718756af72f96e127f8256499ab68f76glennrp    {
809052a479ca718756af72f96e127f8256499ab68f76glennrp      image_info=DestroyImageInfo(image_info);
809152a479ca718756af72f96e127f8256499ab68f76glennrp      image=DestroyImage(image);
809215e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp      (void) ThrowMagickException(&IMimage->exception,
809315e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          GetMagickModule(),CoderError,
809415e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
809515e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "`%s'",IMimage->filename);
809652a479ca718756af72f96e127f8256499ab68f76glennrp#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
809752a479ca718756af72f96e127f8256499ab68f76glennrp      UnlockSemaphoreInfo(ping_semaphore);
809852a479ca718756af72f96e127f8256499ab68f76glennrp#endif
809952a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
810052a479ca718756af72f96e127f8256499ab68f76glennrp    }
810152a479ca718756af72f96e127f8256499ab68f76glennrp
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
8107cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8108cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
81090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
8112cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
81130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
81190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
8127cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8140cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8142da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
8143b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8144b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8145b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
81542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
81592b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
81642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81654e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
81664e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
81672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
81730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
81770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
81830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8187e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8189e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8191e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81938640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81958640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81978640fb5e9b1094f35f8beab436f81661b8a99448glennrp
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
81995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
8200dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
820126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
820326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
820426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
8209dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8210dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8214dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8215823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
8216823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->x_resolution+0.5)/2.54);
8217823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
8218823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->y_resolution+0.5)/2.54);
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8220dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8223dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8224823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution+0.5);
8225823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution+0.5);
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8227991d11dd9c33e65872778b81aff1347cd2878154glennrp
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8230dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
8231dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
8232dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8234991d11dd9c33e65872778b81aff1347cd2878154glennrp
8235823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
8236823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8237823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
8238823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
8239823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
8240991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
824226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8244a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
824526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
824626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
8247a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8249a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
8250a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
8251a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
8252a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
8253a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
8254a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
82550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8256a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
8257a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
82580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8259a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
8260a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
82610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8262a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
8263a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
82640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8265a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
8266a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
82670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8268a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
8269a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
82700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8271a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
8272a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
82730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
82740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
82763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
82773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
82793b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
82803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
82823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
82830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
828526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
82920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82931273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
82943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8296fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
82970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
82980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
83008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
83018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
83020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
83040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
83050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
83060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
83070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
83090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
8311f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
83120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
83140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
83150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
83160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
83170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
83180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
83190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
83210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
83230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
83282b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
83308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
83318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
83325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
833358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
83348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
83350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
83360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
83370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
83380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
83398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
83428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
83430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83452cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
83468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
83470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
83490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
83500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
83538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
83540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83551273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
83564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
83571273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
83581273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
83591273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
83601273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
83614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
83624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
83634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
83640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
83664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
83680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
83725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
83785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
83840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
83880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
83905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
83922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
83938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
83957c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
83967c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
83977c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83987c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84017c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84053c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
84060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8407d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
84088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
84090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8410d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8416d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
84235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
84245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
84255aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84267c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
84277c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
84287c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
84318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
84325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
84355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84365aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84380b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84395aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84405aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
84415aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
84445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
84455aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
84465aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84475aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84485aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
84495aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84505aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
84520b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84535aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84545aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
84555aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84565aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84575aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
84580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
84595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
846326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84648640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
846526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
84665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
84670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
84680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
84690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
84700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
84710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
84720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8474d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
8475d6bf1617e99df0272b231855a933a74e99b6578fglennrp
84765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84788d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
84798d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84818640fb5e9b1094f35f8beab436f81661b8a99448glennrp
84825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
848435ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
84855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
84860f111984738842d27d04aed2a3f823d82a943506glennrp
84870f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
84880f111984738842d27d04aed2a3f823d82a943506glennrp           {
84890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
8490c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              (void) ThrowMagickException(&image->exception,
84910f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
8492c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                "image has 0 colors", "`%s'","");
84930f111984738842d27d04aed2a3f823d82a943506glennrp           }
84940f111984738842d27d04aed2a3f823d82a943506glennrp
849535ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
84965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
8497d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8499d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
8500d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
8501d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8502d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
85030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8504d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8505d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
8506d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
85070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8508d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
8509d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
85125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
85132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8517e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
85180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8520e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
85210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8523e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
85240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85263c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
85278640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
85288640fb5e9b1094f35f8beab436f81661b8a99448glennrp
85298640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8530e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
853358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
85364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
85377c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
85387c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
85397c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
85402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85417c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
85427c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
85437c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
85442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
85464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
85484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
85494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
85514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
85524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
8553a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
85544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
85557c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
85567c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
85577c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
85584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
85614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
85631273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp                mask;
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
85660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
85684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
85690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
85714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
85720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
85744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
85750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
85774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
85780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
85804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
85810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
85834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
85840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
85864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
85870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
85894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
85904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
85910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
85930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
85954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
85984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
8600fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
8601fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
8602fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
8603fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
8604fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
86054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
86062b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
86084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
86097c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
86107c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
86110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
86134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
86144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
86154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
86164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
86174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
86184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
86194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
86204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
86214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
86224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
86255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
86265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
86275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
86285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86328640fb5e9b1094f35f8beab436f81661b8a99448glennrp
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
86340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86352e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
86370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
863839992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
86408d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
86418d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
864335ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
86440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
86469c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
86470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86487c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
86514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
86534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
86544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
86554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
86564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
86584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
86594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
86604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
86650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8666272f23a9dfc9a9104b8cd180c97afba2d20c6683cristy        if ((image_colors == 0) || ((ssize_t) image_colors-1 > MaxColormapSize))
8667f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
86680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
86705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
86710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
86755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
86795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
86800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
868135ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
8682bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
86835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
86880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
86921a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8698bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
87094bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87122b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
87149c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
87150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
87179c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
87180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
87209c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87232b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
87245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
87280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
873117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
873217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
87385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
87390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
874058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87429c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
87430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87443b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87459c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87469c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8751bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87583b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
876098156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
8761f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
87620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
876339992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8767d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8769befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8770befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8771befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
87725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8773befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
87740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8775befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
87765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
87800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
878158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
87820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
87830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8784d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8785d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
87860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8788d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8789d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
87920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
87930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8794d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
87950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8796c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8797c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8798c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8799c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8800c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8801d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8802d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8803d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8804d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8805d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8806d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8807d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
88080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
88090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8815c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
88180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
88224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
88234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
88254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
88305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
88315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
88325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
88335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
88344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
88354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
88364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
88374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
88394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88464383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
88474383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
88482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
88525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
885835ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
885935ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
886035ef824baa82511126ff0072ae30eee0da9c05a3cristy
886122ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
886426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8866a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88713c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
88723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8873991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
887426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
88775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
887917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
888026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
888126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
88821273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
888317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
888417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
888517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
888617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
888717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
888817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
888917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8890a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8891a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
889217a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
889317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
889417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
889517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
88963b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
88970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
88980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
89000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8901a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
890213d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8903a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
89040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
89053b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
89063b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
89070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
89080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
89100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
89110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
89120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
89130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8914a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
891517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8916d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
89173c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
89183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
89193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89203b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
89213c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
89223c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
892317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
892426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
892517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
89340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
89360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
89390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
89400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
89420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
89460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
89480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
89510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
89580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
89620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
89710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89792b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
89860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89952b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
90018640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
90020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90038640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
90048640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
90060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90078640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
90088640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
90095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
90118640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
90120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90138640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
90148640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
90150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90252b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9029823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if ((ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse) &&
9030823b55c200d7fc1818ab539b036a9c24feaecda8glennrp     (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
9031c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
9032c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
9033c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9035c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
90360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9037c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
9038c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
9039c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
9040c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
9041c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
904226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
9043c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
9044c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
9045c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
9046c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
9047e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
9048c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
9049e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
9050e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
9051e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
9052c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
9053c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
905426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
90550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9056c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9058c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
9059c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
9060cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
9061c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
9062c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
9063c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
9064c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
9065c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
90660b206f5daa453dc1035db5890cabc899736dc2d0glennrp
9067c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
9068c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9069c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
90700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9071c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
9072c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
908026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
908126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
908226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
908326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
908426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
908526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
908626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
908726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
90880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
908926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
9090cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
9091cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
90920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
909326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
909426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
909526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
909726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
90985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91012cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
91022cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
910326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
910426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
91143b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
911726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
91182b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
911926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
912126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
912226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
912326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
912426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
912526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
912626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
912726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
912826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
912926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
913026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
913126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
913226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
913326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
913426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
913526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
913626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
913726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
913826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
913926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
914026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
914126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
914226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
914326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
914426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
914526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
914626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9148dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
91495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9156d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
91598d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
91615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
91622b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
91635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
91645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
91660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
91688d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
91730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
91745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
91765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
9177991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
91780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
91830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
91840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
91860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
91870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
91935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
92015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
92053bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
920958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
92140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9215b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
9216b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9217b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92200e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
9221e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
9222991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
9223c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
9224991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
9225c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
9226c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9227c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
9228c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
9229e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
9230e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
92365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
92375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
92385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
92395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
924039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
924139992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
9242f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
92430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92443b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
924539992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
92468640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
92470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
9248d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
92490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9250d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
9251d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
9255d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
92570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
92580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9259d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
92600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
92610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
92640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
926539992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
926639992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
926739992b4dd9b12ef752d55b8e402c069698851f72glennrp
926826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
926926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
927026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
927126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
927226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
9273991d11dd9c33e65872778b81aff1347cd2878154glennrp
927426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
9275dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
927626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
927726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
927826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
927926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
928026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
928126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
9282823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
9283823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
9284823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
9285823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9286823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
9287823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9288823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
9289823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
9290823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9291823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
9292823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
9293823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9294823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
9295823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
9296823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
929726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9298dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9299dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9300dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
93014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
9302dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
930326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
930426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
930526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
930626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
9307dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
930826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
930926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
931026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
931126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
931226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9313dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9314dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
9315dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9316da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
9317da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
9318da8f3a7bfddac2680a3069a490db541e7944edafglennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
9319da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
9320da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
9321da8f3a7bfddac2680a3069a490db541e7944edafglennrp
9322da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
9323da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
9324da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
9326991d11dd9c33e65872778b81aff1347cd2878154glennrp
932739992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
9328991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
93293b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
93300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
93330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
9334991d11dd9c33e65872778b81aff1347cd2878154glennrp
93350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
93360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
93370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
93380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
93390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
9340991d11dd9c33e65872778b81aff1347cd2878154glennrp
93410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
93420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
93440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
93450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
93460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
93470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93483b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
93490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
93500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9351c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
93520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
93530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
93540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
93550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
93560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
93570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
9358991d11dd9c33e65872778b81aff1347cd2878154glennrp
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
9360cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
9361da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
9363991d11dd9c33e65872778b81aff1347cd2878154glennrp
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
9365cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
936726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
93704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
937126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
937226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
937326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
937426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
937526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
937626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
937703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
937826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
937926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
938026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
938126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
938226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
938326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
93879c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
93899c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
9398b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
9399b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
94007202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9402b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
9404b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9406b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
9407b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
9408b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9410b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
9412b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9414b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
9415b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94173b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
94183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9420b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9421b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
94220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9423b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9424e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9426cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
9427cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
94280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9429cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
9447cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
9448cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9450cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9452da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
9453b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
9454b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
9455b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9458ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
9459ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
9460ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
94648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
94668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
94678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
94698d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
94708d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
94750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9482bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
94853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
9487a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
94890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
94920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9496cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,GrayQuantum,ping_pixels,&image->exception);
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
9502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
9503cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
95070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9511cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,RedQuantum,ping_pixels,&image->exception);
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
95130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
9515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
9516cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
95180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
9520b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9521b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
95220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9523cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
95263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
953858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
95395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
95408d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
95440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9548bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
95512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
95578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9559cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,GrayQuantum,ping_pixels,&image->exception);
95602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9563cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RedQuantum,ping_pixels,&image->exception);
95642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
95668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
9571b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
95723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9573b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
95752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9577cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
9578b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
95792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
9581b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
95832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9584cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
95888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
95898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
95908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
95918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
95928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
95938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
95948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
95950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
96000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
96023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
96048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
96058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
96068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
96078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
9608b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
96098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
96108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
96112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
96138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
96168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
96188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9619cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,RedQuantum,ping_pixels,&image->exception);
96202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
96228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9623cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,GrayQuantum,ping_pixels,&image->exception);
96248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9629cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
96308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
96312cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
96338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
96358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96362cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
96388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9639cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBAQuantum,ping_pixels,&image->exception);
96402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
96428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9643cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBQuantum,ping_pixels,&image->exception);
96442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96453b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9646b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
96482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9649cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
9650b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
96518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
96558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
96568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
96578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
96588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
96598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
96608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
96628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
96642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
96668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
96678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
96708640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
96718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
96728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
96742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9675770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
9676770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                   &image->exception);
96772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
96798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
968244757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
96834bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
96844bf89731a90c6e03598950223e19e7be7b95d630glennrp
968544757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9686cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                       quantum_info,GrayQuantum,ping_pixels,&image->exception);
968744757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
96882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
96928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
96942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9696cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
9697d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
96988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
97018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
9702179d075d718a6da568c3600b7e6b159b8a293b41glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
97035eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      quantum_info,IndexQuantum,ping_pixels,&image->exception);
97042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97055eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
97065eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
97075eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97081a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
97095eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
97105eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97115eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
97125eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
97135eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
97148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
9715cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
97168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
97178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
97182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
97198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
97208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
97218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
97228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
97238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
97248640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
97288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9729b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
9730b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9735b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
97360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9738e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
97390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9741e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
97420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
97510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
97600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9767823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
976926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
977026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
977126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
977226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
977326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
977426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
97752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
977626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
9777823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (ping_exclude_pHYs != MagickFalse       ||
9778147bc91f6859c598c4f57b6a162111b2f63614d9glennrp          LocaleNCompare(property,"png:",4) != 0 ||
9779823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
9780823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"units") != 0)
978126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
9782c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
9783c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
9784c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
9785c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
9786c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
9787c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
97882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9789c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
9790c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
97912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9792c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
9793c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
97942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9795c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
979626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
9797c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
9798c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
9799c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
9800c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
980126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
98022cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9803c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
9804c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
9805c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9806c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
9807c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9808c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9809c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
9810c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
9811c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9812c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
9813c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
9814c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
981526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
981626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
981726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
98183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
9821cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
98260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
98280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
98325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
98335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
984303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
98545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
98575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
9869c70af4ac292f8db9a1ab488318912894d412cb8cglennrp     (void) ThrowMagickException(&image->exception,GetMagickModule(),
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
9871c70af4ac292f8db9a1ab488318912894d412cb8cglennrp       "`%s'",image->filename);
98720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9879cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9882cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9885da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (ping_have_blob != MagickFalse)
9886b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9887b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9888b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9889b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9890b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9891b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9892b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9893b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9894b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9895b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9896b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
99000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99395a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
99405a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
99435a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
99445a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
9945e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
9946e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               3-3-3-1, or  3-3-2-1 palette.
9947e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
9948e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
9949e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
99505a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
99515a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
99535a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
99545a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
99555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
99595a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
99605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
99615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
99625a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
99635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
99680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
99695a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
99705a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9975bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9976bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9977bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99955a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
99965a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
99975a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
99985a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
100025a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
100035a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%   or transparency limitations.
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
100083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
100143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
10020bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
10021bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
100253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
10026bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10028bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100303241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
100310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
10032d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
100330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
100340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
100350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
10036cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
100370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
10038d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
10039d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
10040d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
10041d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
10042d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
10043d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
10044d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
100450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
100503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1005221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1005321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1005421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1006421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
100655c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
100665c7cf4e469a4dad7e277783749155932252c52dfglennrp
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
100713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
100733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
100743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10075fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
100763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1008073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
100810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
10090a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
100913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
100923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
100963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
100983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101019c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
101029c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101039c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101089c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
101099c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101109c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101129c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
101139c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
101140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101159c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
101169c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
101170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101189c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101239c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
101249c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101259c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101279c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
101289c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
101290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101309c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
101319c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
101320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101339c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
101378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
101383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
101419c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
101420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101449c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
101450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101479c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
101480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
101509c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
101510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
101539c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
101540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10155bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10156bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10157bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10158bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
10159bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10160bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101629c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10163bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
101670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
101729c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
101730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101759c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
101760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
101789c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
101790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101819c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
101820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
101849c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
101850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10186bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10187bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10188bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10189bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
10190bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10191bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101939c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10194d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
101980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101990dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
102000e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
102010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
102030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
102040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
102050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
102060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
102070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
102090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
102110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
102120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
102130dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
102140dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
102150dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
102160dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * appear in the "include-chunk" list.
102170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
102190e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
102200e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
102210e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102220e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
102230e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
102240e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
102250e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102260e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
102270e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
102280e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102290e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
102300e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
102310e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
102320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1023326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1023426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
1023526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1023626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1023726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1023826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1023926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1024026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1024126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1024226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
10243a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1024426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1024526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1024626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1024726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1024803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1024903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
102505c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
102515c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
102525c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10253acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102545c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
10255acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10256acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10257acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
10258acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
102595c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10260acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102615c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1026226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10263acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10264acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
10265acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10266acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1026703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1026803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1026926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1027003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1027103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1027226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1027303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1027426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1027503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
102762cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
102772cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
102782cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102792cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
102802cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
102812cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102822cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
102832cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1028403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1028503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1028603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1028703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1028803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1028903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1029003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1029103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1029203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1029303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
1029403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1029503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1029603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1029703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1029803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1029903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1030003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1030103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
10302a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1030303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1030403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1030503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1030603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1030703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
103082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1030903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1031003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1031103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1031203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
1031303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1031403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1031503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1031603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1031703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1031803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1031903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1032003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
10321a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1032203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1032303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1032403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1032503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
103262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1032703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1032803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
103292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1033103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
103322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1033403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
103352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1033703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1034003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
103412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1034303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1034403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1034503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
103462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1034803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1035103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
103522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1035403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
103552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10356a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10357a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
103582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1036003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
103612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10362a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10363a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
10364a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1036503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1036603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
103672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1036803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1036903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
103702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1037103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1037203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
103732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1037403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10375ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1037626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1037726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
103785c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
103795c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
103805c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10381acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103825c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
10383acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10384acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10385acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
10386acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
103875c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10388acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103895c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1039026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10391acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10392acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
10393acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10394acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1039503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1039603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1039703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1039803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1039926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1040003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1040126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1040203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
104032cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
104042cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
104052cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104062cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
104072cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
104082cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104092cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
104102cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1041103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1041203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1041303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1041403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1041503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1041603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1041703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1041803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1041903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
1042003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1042103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1042203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1042303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1042403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1042503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1042603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1042703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
10428a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1042903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1043003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1043103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1043203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1043303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1043503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1043603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1043703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1043803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
1043903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1044003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1044103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1044203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1044303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1044403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1044503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1044603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
10447a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1044803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1044903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1045003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1045103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1045403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
104552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1045703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
104582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1046003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
104612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1046303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1046603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
104672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1046903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1047003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1047103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
104722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1047403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1047703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
104782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1048003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
104812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10482a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10483a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
104842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1048503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1048603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
104872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10488a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10489a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
10490a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1049103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1049203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
104932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1049403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1049503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
104962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1049703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1049803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
104992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1050003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10501ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1050226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1050326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1050403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1050526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1050626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1050726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
1050826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1050926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1051126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1051226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
1051426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1051526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1051726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1051826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1052026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1052126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1052326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1052426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1052526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1052726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1052826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1052926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1053126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1053226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1053426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1053526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1053726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1053826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
10540a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
10541a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10542a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1054426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1054626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1054726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1054926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1055026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1055226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1055326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10554b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10556b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
105590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
105620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1057903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10596bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
10600fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
106083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
106250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
106300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
106320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
106390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
106410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
106490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
106513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
106520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
106550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
106573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
10711f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
107130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10716e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
10717e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
107213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1072903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
107304e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
107314e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10745f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
107460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10748f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
107490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
107520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
107550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
107580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
107610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
107640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
107670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
107700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
10776cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
107843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
10800bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1080203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1082303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
108240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10826e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10827cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10828e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
108290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10831e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10832cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10833e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
108340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1084703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1084835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1086403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1086635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1086735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1086935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1087035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1087235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1087335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1087535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1087635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
108773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1088903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1089235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
108940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1089535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
108970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
109033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1090535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
109070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1090835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
109100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1091635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1091735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1093203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10933bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10934bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
109403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1094303812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10956bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10959bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
109643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10965e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10966f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10971bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
109750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10979bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1098003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10990e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10991e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11001e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
11002bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1100403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
110093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
110123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11040e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
11041e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
110450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
110530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
110550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11059e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
11060e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11063e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
11067bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
110683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1106903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
110733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
11080cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1108503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
110883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
110920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1112721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1112803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11142fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
111453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
111493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1115173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
111713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
111723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
111833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1118521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1118803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1118903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1119003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
111983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11208bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11218bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11221bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11225d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11239fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1124873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
112563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
112613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
112643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
112713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
112723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
112890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11291e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
112920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11300e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
113010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11303e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
113040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
113080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
113120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
113160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
113200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11323e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
113240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
113280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
113313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
113333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
113363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
113373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
113383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
113463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
113473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
113513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
113523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
113583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
113663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
113673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
113683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
113703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
113753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
113763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
113773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
113910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
113950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
113980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
114010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
114063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
114070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
114100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
114120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
114160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
114240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
114283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
114323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
114333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
114353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
114383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
114393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
114403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
114423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
114433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
114440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
114463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
114470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
114510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
114543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
114560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
114613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
114723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
114733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
114913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
114940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
115080261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
11509d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
11510d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
11511d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
11512d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
11513d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
11514d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
11515d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
115163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
115173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
115193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
11521cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
11522cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
115233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
115243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
115250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
115273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
115280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
115310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
115333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
115343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
115353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
115363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
115403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
115413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
115483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
115503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
115513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1155203812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
115534e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
115544e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
115553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
115563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
115573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
115583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
115593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
115603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
115650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
115740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
115773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
115813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
115860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
115893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
115950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
115983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
116033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
116063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
116123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
11613bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1161403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
116223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1162803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
116293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
116303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
116313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
116323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
116330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
116360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
116383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
116390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
116413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11643e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
11644e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
116450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
116473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11648e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
116490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
116513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11652e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
116533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
116553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
116583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
116623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
116673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1166803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
116690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
11671e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11672cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11673e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
116740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
11676e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11677cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11678cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
116790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
116813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
116823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
116833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
116863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
116883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
116913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
116923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1169403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1169535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
116973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
116983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
116993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
117013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
117033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
117043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
117063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
117073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
117093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1171003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
117113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1171235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1171335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
117143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1171535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1171635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
117173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1171835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1171935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
117203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1172135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1172235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
117233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
117243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
117253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
117263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
117293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
117313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
117323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
117333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
117343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1173503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
117360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
117383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1173935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
117403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
117410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1174235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
117433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
117440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
117463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
117493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
117513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1175235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
117540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1175535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
117563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
117570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
117593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
117623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1176335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1176435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
117653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
117743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
117803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1178303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
117843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
117853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1179603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
117973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
117993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
118003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
118013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
118033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
118043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
118053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
118063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
11807bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
118123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
118143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1181603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
118170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11818bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
118193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
118223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
118240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
118263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
118273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
118283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
118293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
118323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
118333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
118363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
118393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
118403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
118443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
118483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
118493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
118503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
118533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
118563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
118573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
118583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
118593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
118603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
118613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
118663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
118673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1186803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
118690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
118723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
118743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
118760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
118783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
118793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
118803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
118813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
118843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
118863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
118963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
118993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
119043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
119053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
119083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1190903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
119103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
119123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
119133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
119143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
119373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1193803812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
119493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1195003812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
119513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
119533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
119543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
119553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
119563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
119573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
119583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
119603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
119613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
119624e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
119633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
119653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
119723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
119783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
119813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
119882f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11989b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
119902f2e514554975d510c88df54de98c6cdc1080f1cglennrp
119912f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
119922f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
119932f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
119942f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
119952f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
119962f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
119972f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
119982f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
119992f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
120002f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
120012f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
120022f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
12003a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
120042f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
120052f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
120062f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
120072f2e514554975d510c88df54de98c6cdc1080f1cglennrp
120083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
120093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
120103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
120123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
120133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
120143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
120153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
120163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
120203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
120230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
120260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
120280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
120323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
120333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
120353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
120373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1203803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
120403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
120443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
120463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
120470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
120493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
120500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
120523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12053d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1205439992b4dd9b12ef752d55b8e402c069698851f72glennrp
120553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
120563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
120593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
120600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
120623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
120633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1206439992b4dd9b12ef752d55b8e402c069698851f72glennrp
120653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
120663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
120683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12069d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
120703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12071