png.c revision cb395ac9c5c50c2829a9988f95fd8aea7af82c00
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
1529cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1532faa852bad40107edae19405e76a299057668d795glennrp    pass,
1533faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1534faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1535faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1536faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1537faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1538faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1540a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  LongPixelPacket
1541a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    transparent_color;
1542a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
15444383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1547faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1548faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1549faa852bad40107edae19405e76a299057668d795glennrp
1550faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1551faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1552faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1553faa852bad40107edae19405e76a299057668d795glennrp
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1564faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1565faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1566faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1567faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1568faa852bad40107edae19405e76a299057668d795glennrp
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
1573cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
15825c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
159239992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
1608fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1611cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
161425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
162061b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
162161b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
162261b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
162361b4c957269727a0a2526edc2331881da8346100glennrp    {
162461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
162561b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
162661b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
162761b4c957269727a0a2526edc2331881da8346100glennrp    }
162861b4c957269727a0a2526edc2331881da8346100glennrp#  endif
162961b4c957269727a0a2526edc2331881da8346100glennrp#endif
163061b4c957269727a0a2526edc2331881da8346100glennrp
163161b4c957269727a0a2526edc2331881da8346100glennrp
1632ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1635a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
1636a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
1637a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
1638a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
16390e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
16400e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
16410e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
16420e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
16430e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.opacity=65537;
16440e319739731741c52a6303723e0c8678a0df5579glennrp
1645cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
1646cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
1647cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
1653cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
1654cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
1657cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
16630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
16710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1678cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
16790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1680faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1687cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
16920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
16947b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
16957b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
16967b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
16977b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
16980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1704faa852bad40107edae19405e76a299057668d795glennrp
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1740991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1741991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1742991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1756991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1760faa852bad40107edae19405e76a299057668d795glennrp
1761faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1762faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1763faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1764faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1765faa852bad40107edae19405e76a299057668d795glennrp
1766faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1767faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1768faa852bad40107edae19405e76a299057668d795glennrp
1769faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1770faa852bad40107edae19405e76a299057668d795glennrp
1771faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1773faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1774faa852bad40107edae19405e76a299057668d795glennrp        {
1775faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1776faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1777faa852bad40107edae19405e76a299057668d795glennrp        }
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1779faa852bad40107edae19405e76a299057668d795glennrp
1780faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1782faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1786e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1787e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
17880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1791faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
17920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1795faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
17960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1799faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1802faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1803faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1808e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
1809e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
1810e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1811e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
1812e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
1813e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1814e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
1815e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1846cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1847cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        (mng_info->global_srgb_intent);
18480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1851cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1852cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
18530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1856e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1864faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1865faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1866faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
18670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1876faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1877faa852bad40107edae19405e76a299057668d795glennrp    {
1878faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1879faa852bad40107edae19405e76a299057668d795glennrp        {
1880faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1881faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1882faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1883faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1884faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1885faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1886faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1887faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1888faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1889faa852bad40107edae19405e76a299057668d795glennrp        }
1890faa852bad40107edae19405e76a299057668d795glennrp    }
18910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1892faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1909e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1911e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1912cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
1913cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
1914faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1915faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1916faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1917faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1920faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1922905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
1923905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
19240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1928e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1929e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1933faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1934faa852bad40107edae19405e76a299057668d795glennrp    {
1935faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1936faa852bad40107edae19405e76a299057668d795glennrp        {
1937faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1938faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1939faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1940faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1941faa852bad40107edae19405e76a299057668d795glennrp        }
1942faa852bad40107edae19405e76a299057668d795glennrp    }
1943faa852bad40107edae19405e76a299057668d795glennrp
1944faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19570881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19580881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19590881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1970e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1971e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1974823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
1975faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
19840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
1986faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
19920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1993faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2010faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2019faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2020faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2043faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2044faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2047faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20562cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2058faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2059faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2060faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20632cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20652cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
20662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
20672cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20682cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20692cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
20712cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20732cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
20740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20752cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
20762cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
20770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20782cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
20792cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
20800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20812cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
20822cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
20830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
20852cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
20862cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
20882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
20892cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
20902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20912cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
20932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
20950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20972cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
20982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20992cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
21002cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2102faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2105faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2108faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2110f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21132cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2114e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2115e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2116e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2117e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2121a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2122faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2125a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
213035ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
213135ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
213235ef824baa82511126ff0072ae30eee0da9c05a3cristy
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2137f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2139faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2140faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2141faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2142faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2143faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2144faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2150faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2155a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2156a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2157a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2158a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2159a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2160a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2161a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2162a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2163a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
2164a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.opacity= scale_to_short*ping_trans_color->gray;
216505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2166faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21680f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
21690f111984738842d27d04aed2a3f823d82a943506glennrp              {
21700f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21710f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
21720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21730f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21740f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
21750f111984738842d27d04aed2a3f823d82a943506glennrp              }
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2185faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2190faa852bad40107edae19405e76a299057668d795glennrp
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2192faa852bad40107edae19405e76a299057668d795glennrp
2193faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2194faa852bad40107edae19405e76a299057668d795glennrp
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2199bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2201bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2204faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2205faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2216faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2217faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2218faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2219faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2220faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2222befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2223befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2224befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2226befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2227befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2235faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2244bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2260faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2270bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2283faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
22840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2288bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2296147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2297cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2298cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2299147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2300147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2301147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2302147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2303147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2304147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2305147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_width);
2306147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.width           ",msg);
2307147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2308147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_height);
2309147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.height          ",msg);
2310147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2311147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
2312147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.bit_depth       ",msg);
2313147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2314147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_color_type);
2315147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.color_type      ",msg);
2316147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2317147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",
2318147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        (int) ping_interlace_method);
2319147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.interlace_method",msg);
2320cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2321147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23280ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2329347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2330347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2334e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2338cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2352cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2353cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
23540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2356cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2357cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
23580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2359cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2368faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2375cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
23790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2380cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
2381cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
23820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
23860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
23887b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
23897b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
23907b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
23917b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
23920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2396ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
23970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2398ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2399ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2401c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2402c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2403c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2404c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2405c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2406c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2407c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2410c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2411c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2412c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2413c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2414c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
2415c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
2416c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        int
2417c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          depth;
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2419c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        depth=(ssize_t) ping_bit_depth;
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2421c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2422c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2423c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2424c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
24250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2426c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2427c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2428c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2429c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
24300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2431c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2432c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
24330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2434cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
2435c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2437c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (q == (PixelPacket *) NULL)
2438c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
24390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2440c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#if  (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
2441c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp/* code deleted from version 6.6.6-8 */
2442c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#else  /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2444c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2446cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayQuantum,ping_pixels+row_offset,exception);
24470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2448c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2450cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayAlphaQuantum,ping_pixels+row_offset,exception);
24510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2452c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2454cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBAQuantum,ping_pixels+row_offset,exception);
24550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2456c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2458cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              IndexQuantum,ping_pixels+row_offset,exception);
24590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2460c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2462cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBQuantum,ping_pixels+row_offset,exception);
2463c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#endif
2464c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2465c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2466c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2467a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2468a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2469a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2470a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2471c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2472c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
24735aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
24745aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
24755aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                   (q->opacity != OpaqueOpacity))
2476c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2477a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2478a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2479a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2480a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2481c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2482c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2483c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
24844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
24854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
2486a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    (ScaleQuantumToShort(q->red) == transparent_color.red &&
2487a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->green) == transparent_color.green &&
2488a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->blue) == transparent_color.blue))
24894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2490a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2491a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2492a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
24934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
24944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
24954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2496c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                q++;
2497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
24990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2500c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2501c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2502c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2503c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
25040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2505c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2506c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2507c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2508c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2510c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
25110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2512c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
25137a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2514c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25157a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25167a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25177a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2522c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2534faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2546faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
2547c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
2550c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2551cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25575c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2558cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2560c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2561faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2568bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2577bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
258347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2586bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2596bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
260247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
261647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2619faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
2629c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                if (q->opacity != OpaqueOpacity)
26300b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
264047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
265947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2660faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
2665c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
26660b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
26840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2685faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
2688afee4d36aae894a74306a3c492437ca55dce2badcristy                  q->opacity*=65537L;
268946f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
2690afee4d36aae894a74306a3c492437ca55dce2badcristy                  if (q->opacity != OpaqueOpacity)
26910b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
269547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
269947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2700faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
2703c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
27040b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
271147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
271447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2723bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
272480ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27297a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27307a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2731cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2732cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
273347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27347a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27357a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27367a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2738c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27397a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
274247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2746c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2749c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2750c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
2751c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2752c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
2753c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2754c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
2755c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2756c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
2757c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
27585aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
27595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
2761a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
27625aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
27635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
2764c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
2765c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
2766c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2767b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2768b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27705c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27715c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2772aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27735c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27745c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27755c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27765c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27775c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2778aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27795c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
278047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2787cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2791cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
279847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2799faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2809c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28103c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2811c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2815c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2821c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
282247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
283647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2837a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
2838a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
2839a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
28400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2846c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2849c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2852a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
2853a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
2854a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
28550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
2857a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
2858a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
2859a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2864a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 0 /* I have not found a case where this is needed. */
28650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  q->opacity=(Quantum) OpaqueOpacity;
28684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
2869a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
28700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
28750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2876c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
28770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2878a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
2879c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2883b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2884b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2885b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
288647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
28950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
2897cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        {
2898cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (void) Magick_png_read_raw_profile(image,image_info,text,(int) i);
2899cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp          num_raw_profiles++;
2900cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        }
29010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29193e37b4a7f21b6ae84f32c7748d999d86e17c201aglennrp
2920823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          /* Don't save "density" or "units" property if we have a pHYs
2921823b55c200d7fc1818ab539b036a9c24feaecda8glennrp           * chunk
2922823b55c200d7fc1818ab539b036a9c24feaecda8glennrp           */
2923823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
2924823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (LocaleCompare(text[i].key,"density") != 0 &&
2925823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              LocaleCompare(text[i].key,"units") != 0))
29263e37b4a7f21b6ae84f32c7748d999d86e17c201aglennrp             (void) SetImageProperty(image,text[i].key,value);
29270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
292997f90e23c85b9c58387880125c29d8c99126f83aglennrp          {
293097f90e23c85b9c58387880125c29d8c99126f83aglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
293197f90e23c85b9c58387880125c29d8c99126f83aglennrp              "      length: %lu",(unsigned long) length);
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
293497f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
29350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29393c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
295273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
296047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2993faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
29950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2996faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2997faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2998faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2999faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3000faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3001faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3002faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3003faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
30040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3005faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
302447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30300a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
30310a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp   /* Set image->matte to MagickTrue if the input colortype supports
30320a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
30330a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
30340a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
30350a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
30360a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
30370a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
30380a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        MagickTrue : MagickFalse;
30390a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3040cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3041cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3042cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3043cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3044cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3045cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_text != 0)
3046cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3047cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
3048cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) FormatMagickString(msg,MaxTextExtent,
3049cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d chunks were found", num_text);
3050cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text                 ",msg);
3051cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3052cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3053cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3054cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3055cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) FormatMagickString(msg,MaxTextExtent,
3056cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
3057cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text-encoded profiles",msg);
3058cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3059cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3060cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%s",
3061cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        "chunk was found");
3062cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3063cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
3064cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:gAMA                 ",msg);
3065cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3066cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
3067cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:cHRM                 ",msg);
3068cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3069cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
3070cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:bKGD                 ",msg);
3071cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3072cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
3073cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:iCCP                 ",msg);
3074cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3075cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
3076cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:sRGB                 ",msg);
3077cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3078cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
3079cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:pHYs                 ",msg);
3080cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3081cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
3082cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:tRNS                 ",msg);
3083cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3084cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3090cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3092cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
311121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
311221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
312947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
313347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3136fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
314047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
314347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
314847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3149dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
315147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
315673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
315747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
316047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
317147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
318947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
319147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
320047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
32040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
321047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
32190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
322197f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
322297f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
322397f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
322497f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
322597f90e23c85b9c58387880125c29d8c99126f83aglennrp
322697f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
32280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32804383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
32814383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
32824383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3321bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3335fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
33380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
33470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
33490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
33520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
33800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
33830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3391e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3392e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
339947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
34030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3407bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
34090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
341247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
341947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3427bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3429bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
343547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
343847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
344347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3447f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
344847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3450f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
345147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
345447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
345847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
346247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
346647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
347047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
347447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
347847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
348447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
348747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
350373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
350447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
350747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
35100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
35170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
35210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
352873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
35290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
35350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
35460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
35500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
35530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
35620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
35650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
356803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
358547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
359247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
359547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
360447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3612bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
361403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
362947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
36490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
36798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
36800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
36908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
36918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
36928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
36938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
36948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
36958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
369847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3707e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3708cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
371947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37285eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
37295eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
37300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
373747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
37498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3765fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
37780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
380747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
38110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
38140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
38170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
38310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
38350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
384147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
38470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
385803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
38640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
38730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3875bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
388047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3882bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3886bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
38920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
390447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
390547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
39130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
39150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
39160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
39190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
39210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
39250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
39320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
39360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
397821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
397921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3999fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
401047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
401147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
401347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40143b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
401747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
401847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
402073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
40210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
402547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
402647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
40340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
40420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
405047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
40560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
40620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40764383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
407721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
407821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
40794383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4086bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4111bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4117bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
414338ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
414438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
414538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4146bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
416847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
416947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4175fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
41790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
41820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
418647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
418747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
418847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
418973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
41900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
419447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
419547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
420547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
420947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
421047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4213bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4214bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
421847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4261e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4262e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
42660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
42690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
42720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
427647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
427947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
428247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
42960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
43070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
431247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
43170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
43240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
43320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4333bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
43350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4339e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4341e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
43458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
43460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
43490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
43530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
43560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
43608182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
43640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
43670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
43700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
437747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
43790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
43820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
43900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4391e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4392e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4393f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
43940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4396bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4398bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
44000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
44030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
44160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
44208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
44210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
44240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
44330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4435e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
44360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4438e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
44520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
44810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
44840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
44910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
44920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
44940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
44950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4499e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4500f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
45010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4503e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4504f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
45140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
45210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
45440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
45470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
457047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
457347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
457447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
45800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
458835ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
46030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
460747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4613bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
462012560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4628bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46318182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
46380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
464547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
464647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
46508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
46518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
46538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
46558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
46578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
46598182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
46618182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
466647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
467047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4678e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4679cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
468447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
468847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4691fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
469847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
470147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
47110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
471547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
47190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
47230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
472647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
472747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
472947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
473247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
473447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
474647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
47508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
47510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
47538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
47540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4755bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4756bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
47570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
47600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4765e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
476747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4770bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4771bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
47720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4773bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4774bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
47750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4776bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4777bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
47780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
47810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4786e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
478847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
47940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4798e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4799e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
480047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
48080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
48110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4812bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4820e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4821e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
48220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
482647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
483047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
483747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
48630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4867e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4868e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
488547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
489747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
492147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
492247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4934bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
494647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4949bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
495347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
495447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
497447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4981bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
498447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
498547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
49868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
49870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4990e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4991e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
49920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
49950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
500647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
501047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
502247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
50290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5033e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5034f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
503547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
50400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
504547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
506347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
506747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
507447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
507747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
50940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
50970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
51000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
511147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
511747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
512347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
512647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
513247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
513547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
514147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
514447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
515047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
515347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
515947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
516247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
516847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
517147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
517747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
518147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
518947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
520847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
521547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
521847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
522547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
522847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
523347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
52498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
52518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
525547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
526447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
527047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
527547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5278bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
528847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
529147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
529447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
529747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
530047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
530347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
530647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
531447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
531747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
532047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
532547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
533547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
534247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
534547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
535147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
535947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53608182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
53618182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5374bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
538447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
539147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
539547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
540247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
540547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
540647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
540747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5419e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5420e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
543747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
544447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
54470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
54490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
545947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
54700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5474e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5475e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
547947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
548647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
549347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
54990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
55020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
55110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
55200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
552647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
553047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
553547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5536bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
553747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
554947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
556247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
559547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
559847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
560047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
560147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
560347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56064e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
560747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
561047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
561347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
561547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
561647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
561847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
562247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
562547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
562747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
562847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
563047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56334e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
563447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
563747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
564047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
564247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
564347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
564547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5659bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
567447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
567547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
567947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
568147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5705bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
570947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5710bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
571847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
572947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
573447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
573747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
574047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
574347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5752e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
575847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
576747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
577047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5771bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
577547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5777bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
577847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
578147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5782bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
578447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
578747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
579147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5792bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
579847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5804bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
581047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5813fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
582447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
582947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5834bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5837bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5839bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5840bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
584247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5844bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5847bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
584947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
585947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
586547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
586847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
588047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
588347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
588647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5905e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5907bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
591547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5916bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5919bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5920bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
592147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5923bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
592447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5925bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5926bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
592747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5928bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
593047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
593347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
594147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
594647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5952bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5955bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5958bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
596447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
597447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
598347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5988bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
599747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6007bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
601047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6011bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
601947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
605347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6069bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6070bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
607647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
608847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61112b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
61122b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
61132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
61142b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
61152b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
61162b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
61172b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
61182b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
61190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
61208640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
61218640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6123d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
612547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6129bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6132d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6136d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
613847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
614047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
614447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
61550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
616647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
617047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
61830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
61860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
61910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
620247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
620647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
62110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
621647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
622247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
623047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
623547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
624147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
624447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
624747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
62550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
62610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
626647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
62720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
62740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6277e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6278e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
62790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
628747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
629047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6292e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
629347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6298e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6310bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
631547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
631847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
632147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
632447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
633347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
633647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
635347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
636347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
636647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6368e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6369e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
637047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6372f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6373f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
637447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6375f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6376e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6377e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6378f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6379f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
638047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
638447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
638747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
639025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
639547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
639847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
640147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
640625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6429bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
644547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
645147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
645947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
646347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
647447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
648247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
648547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
649147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
649647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
650147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
650447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
650947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
651447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
652447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
652847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
653547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
653847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
654347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
655147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
655647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
656447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
657147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
657847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
657918b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6580cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
658118b17443128598500357da7bff2f01683cf32890cristy#endif
658247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
661347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6615cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
6616cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
662125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
6697cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
67250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
67260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
67280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6747f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
674947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6750bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
675747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
676447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
676747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6773cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
67744383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
678847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
678947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
679047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
679247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
6796cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
679847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
679947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
680047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
680147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
680247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
680347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6804cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
6805cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
6806cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
680747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
680847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
680947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
681047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
681147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
681247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
681347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
6814cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
681547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
681747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
682047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6824b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6825b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6827b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6829b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6830b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6831b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6832b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6833b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6834b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6848cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6849cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6850e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6851e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
68525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
685339992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
685439992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
68575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
68585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
68595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
68675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
68685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
68695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
687458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
687521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
687658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
687758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
6878da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
6879fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
6880d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
68818d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
688239992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6883991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6884991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6885991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
688626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
688726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
688826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
6889e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
689026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
689126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
689226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
689326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
689426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
689526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
689626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6897e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
689826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
689926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
690026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
690126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
69020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
69030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
690482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
6905d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
6906d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6911bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6916cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
6919f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
69200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
69215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
69225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
69235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
69245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
69255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
69265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6927bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
69285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
69295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6936dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6937fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
6938f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
69398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
69408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
69418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
6942dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6943dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6944dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6945dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6946dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6947dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
6949fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6951b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
6952b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
6953b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6955cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
69590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
69605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
69615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
69625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
69635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
69645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
69655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
69675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
69685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
69695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
69705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
69715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
69735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
69745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
69755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
69765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6977dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
6978dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
6979dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
6980dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6981da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
6982d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
69838d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
698439992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
6985991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6986991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6987991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6988991d11dd9c33e65872778b81aff1347cd2878154glennrp
69890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
69900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
6991dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
69920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
69930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
69940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
69950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
69960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
69970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
69980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
69990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7000dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
70010e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
70020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
70030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
70040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
70060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
70088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
70098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
70108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7011fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7012fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7013fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7014fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7015fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7016fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7017fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7018fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7019fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7020fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7021fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7022fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
7023fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
70260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
70273241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
70283241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
70293241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
70303241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
70313241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
70323241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
70333241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7034a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7035a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7036a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7037a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7038a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7039a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7040a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7041a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7042a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7043a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7044a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7045a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
70462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
70472b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
70482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
70492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
70502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
70512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
70522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
70532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
70548640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
7055c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
70568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
70578640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
70588640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
70598640fb5e9b1094f35f8beab436f81661b8a99448glennrp
7060c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
7061e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
7062e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
7063e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * RGBA palette and run again, and finally to a simple 3-3-2-1 RGBA
7064e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * palette.  The final reduction can only fail if there are still 256
7065e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * colors present and one of them has both transparent and opaque instances.
7066c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
706782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
706882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
7069d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
707082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
7071d337164012450d70d62e71cf4a308a29004f7d57glennrp  for (j=0; j<5; j++)
7072d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
7073d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
7074d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7075d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
7076d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
7077d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7078d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
7079d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
7080d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
7081d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
7082d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
7083d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7084d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * If image->matte is MagickFalse, we ignore the opacity channel
7085d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
7086d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7087d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
7088d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
7089d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
7090d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7091d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
7092d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
7093d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
70943c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
709552a479ca718756af72f96e127f8256499ab68f76glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
709652a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 0 /* Shift */
709752a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 1 /* Scale */
709852a479ca718756af72f96e127f8256499ab68f76glennrp#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
709952a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 8
710052a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 0x0101
710152a479ca718756af72f96e127f8256499ab68f76glennrp#else
710252a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGK 24
710352a479ca718756af72f96e127f8256499ab68f76glennrp#  define PNGM 0x01010101
710452a479ca718756af72f96e127f8256499ab68f76glennrp#endif
710552a479ca718756af72f96e127f8256499ab68f76glennrp
7106d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   ExceptionInfo
7107d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *exception;
71088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7109d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
7110d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
71118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7112d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   PixelPacket
7113d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
7114d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
7115d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
71168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7117d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register IndexPacket
7118d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *indexes;
71198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7120d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register const PixelPacket
7121d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *s,
7122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *q;
7123d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7124fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   register PixelPacket
7125fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
7126fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7127d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7128d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7129d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
7130d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7131d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7132d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7133d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7134d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
7135d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7136d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
7137d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7138d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
713903812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7140d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
71413c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7142fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
71437ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
71447ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7145d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
71468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7147d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "        i    (red,green,blue,opacity)");
71482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7149d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
71507ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
7151d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7152d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7153d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7154d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7155d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7156d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7157d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
71587ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
71592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7160d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
7161d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
7163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7166d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
7171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7172d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
7173d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
71742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7176d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
717783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
7179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "        (zero means unknown)");
71817ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7182d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7183d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      Regenerate the colormap");
7184d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
71857ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7186d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     exception=(&image->exception);
7187d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7188d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
7189fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
7190fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
7191fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
71922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7193d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
7194d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
71967ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7197d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (q == (PixelPacket *) NULL)
7198d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
719997fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
7200d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
7201d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7202d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (image->matte == MagickFalse || q->opacity == OpaqueOpacity)
72038d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7204d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
72058d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
7207d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7208d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0]=*q;
7209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0].opacity=OpaqueOpacity;
7210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
7211d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7212d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7213d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
7214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(opaque+i, (PixelPacket *) q))
7216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7217d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7218d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_opaque &&
7220d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque < 259)
7221d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
7223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i] = *q;
7224d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i].opacity = OpaqueOpacity;
7225d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
72268d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
72278d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7228d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (q->opacity == TransparentOpacity)
72298d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7230d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
72318d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7232d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
7233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[0]=*q;
7235d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.red=(unsigned short)(q->red);
7236d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.green=(unsigned short) (q->green);
7237d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.blue=(unsigned short) (q->blue);
7238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.gray=(unsigned short) (q->blue);
7239d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
7240d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7241d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7242d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
7243d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(transparent+i, (PixelPacket *) q))
7245d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
7249d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
7250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
7252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[i] = *q;
7253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
72548d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
72558d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
7259d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7260d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
7261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[0]=*q;
7263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
7264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
72658d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7266d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
7267d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(semitransparent+i,
7269d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          (PixelPacket *) q) &&
7270d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          q->opacity == semitransparent[i].opacity)
7271d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7273d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7274d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
7275d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
7276d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
7278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[i] = *q;
7279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
72818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
7282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           q++;
7283d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
7284d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
72853c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (ping_exclude_bKGD == MagickFalse)
7287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7288d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
7289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
7290d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
7292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7293a080bc32a4a8b2ffec83fd836a28753959175363glennrp             if (IsColorEqual(opaque+i, &image->background_color))
7294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             break;
7295d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7296a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7297d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
729803812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
7299d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i]=image->background_color;
7300d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i].opacity = OpaqueOpacity;
7301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               number_opaque++;
730203812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
7303a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
7304a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7305a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
7306d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
73093241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7310a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
7311a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
7312a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
7313a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
7314a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
7315a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
7316a080bc32a4a8b2ffec83fd836a28753959175363glennrp
7317d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
7320d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7321d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
73223241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
7324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
7326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73273241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7328fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
7329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7330d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
7331d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
73323241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7333d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
7334d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7335d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
7336d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
73386185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (q == (PixelPacket *) NULL)
7340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
73416185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
7343d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
7344d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
73456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7346d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_color == MagickFalse)
7347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7348d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7349d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
7350d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   {
7351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != s->green || s->red != s->blue)
7352d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7353d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_color=MagickTrue;
7354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_non_bw=MagickTrue;
7355d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          break;
7356d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7359d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
73603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7361d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
7362d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7363d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7364d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
73656185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
7366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != 0 && s->red != QuantumRange)
7367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7368d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
7369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7372d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
7373d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           }
7375d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
7377d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
7378d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         PixelPacket
7380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
7381d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7382d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
7383d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
7384d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7385d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7386d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
7387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7388d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
7389d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7390d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
7391d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7392d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
73933241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7394d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
7395d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
73963241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7397d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
7398d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
7399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7400d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
7401d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
7402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
7405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
7406d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7407d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
7408d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7409d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
7410d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
7412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
7413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
7414d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
7415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
7416d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
7417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
7418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7420d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
7423d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
7424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
74263241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7427d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
7428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
7429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
7430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
7431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
7432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
74346185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
7435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
7436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
7438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
74392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
7442d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
7445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (AcquireImageColormap(image,image_colors) ==
7447d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
7448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               ThrowWriterException(ResourceLimitError,
7449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "MemoryAllocationFailed");
7450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
7452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
7453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
7455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7456d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
7458d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
7459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
7462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7464fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
7465fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
7467d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
7468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              q=GetAuthenticPixels(image,0,y,image->columns,1,
7469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  exception);
74703c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7471d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (q == (PixelPacket *) NULL)
7472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
74733c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              indexes=GetAuthenticIndexQueue(image);
7475d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
7477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7478d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
747903812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
7480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
7481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      image->colormap[i].opacity == q->opacity) &&
7482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (IsColorEqual(&image->colormap[i],
7483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         (PixelPacket *) q)))
74846185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
7485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    indexes[x]=(IndexPacket) i;
7486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
74876185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
748803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
7489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                q++;
7490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
7493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
7494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
7495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
7497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
7502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
7504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7505d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 "       i     (red,green,blue,opacity)");
750783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7508d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
7509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
751072988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
7511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7512d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7513d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
7514d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
7515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
7516d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
7517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
7518d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].opacity);
7519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
75206185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
75216185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
75223c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7523d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
7524d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
7526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
7527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
75283c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7530d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
75313c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
7533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7534d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
7535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
753603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
7537d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
75406185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
7542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
7544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
75456185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7546d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7547d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
7549a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7552d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
7553a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
7555d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
7557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
75616185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
756203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
756303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
7564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
75653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7566c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
7567c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7568fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7569c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
7570c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
7571c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
7572c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
7573c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
7574c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7575fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7576c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
7577c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     * opacity to 0 or OpaqueOpacity
7578c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7579c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (number_semitransparent != 0)
7580c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7581c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7582c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
7583fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7584c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
7585c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7586c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          r=GetAuthenticPixels(image,0,y,image->columns,1,
7587c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              exception);
7588fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7589c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (r == (PixelPacket *) NULL)
7590c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
7591fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7592c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
7593c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
759482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r->opacity = r->opacity > TransparentOpacity/2 ?
759582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                   TransparentOpacity : OpaqueOpacity;
7596c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              r++;
7597c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7598c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7599c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
7600c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
7601fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7602c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
7603c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
7604c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
7605c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                image->colormap[i].opacity =
760682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    image->colormap[i].opacity > TransparentOpacity/2 ?
760782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    TransparentOpacity : OpaqueOpacity;
7608c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7609c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7610c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7611c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7612c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
7613e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
7614e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
7615e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
7616c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7617d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
7618d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
7619d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7620d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7621d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
7622d337164012450d70d62e71cf4a308a29004f7d57glennrp
7623d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
7624d337164012450d70d62e71cf4a308a29004f7d57glennrp
7625d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.red=
7626d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7627d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.red) >> PNGK) & 0xf0)     )  |
7628d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7629d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7630d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.green=
7631d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7632d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.green) >> PNGK) & 0xf0)     )  |
7633d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7634d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7635d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.blue=
7636d337164012450d70d62e71cf4a308a29004f7d57glennrp            ((((((size_t)
7637d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.blue) >> PNGK) & 0xf0)     )  |
7638d337164012450d70d62e71cf4a308a29004f7d57glennrp            (((((size_t)
7639d337164012450d70d62e71cf4a308a29004f7d57glennrp            image->background_color.blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7640d337164012450d70d62e71cf4a308a29004f7d57glennrp
7641d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7642d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7643d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
7644d337164012450d70d62e71cf4a308a29004f7d57glennrp
7645d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
7646d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7647d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
7648d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7649d337164012450d70d62e71cf4a308a29004f7d57glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7650d337164012450d70d62e71cf4a308a29004f7d57glennrp                exception);
7651d337164012450d70d62e71cf4a308a29004f7d57glennrp
7652d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (r == (PixelPacket *) NULL)
7653d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
7654d337164012450d70d62e71cf4a308a29004f7d57glennrp
7655d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
7656d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
7657d337164012450d70d62e71cf4a308a29004f7d57glennrp              if (r->opacity == TransparentOpacity)
7658d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7659d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red = image->background_color.red;
7660d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green = image->background_color.green;
7661d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue = image->background_color.blue;
7662d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7663d337164012450d70d62e71cf4a308a29004f7d57glennrp              else
7664d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7665d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red=
7666d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->red) >> PNGK) & 0xf0)    )  |
7667d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7668d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green=
7669d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->green) >> PNGK) & 0xf0)    )  |
7670d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7671d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue=
7672d337164012450d70d62e71cf4a308a29004f7d57glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xf0)    )  |
7673d337164012450d70d62e71cf4a308a29004f7d57glennrp                       (((((size_t) r->blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7674d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7675d337164012450d70d62e71cf4a308a29004f7d57glennrp              r++;
7676d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
7677d337164012450d70d62e71cf4a308a29004f7d57glennrp
7678d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7679d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
7680d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7681d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7682d337164012450d70d62e71cf4a308a29004f7d57glennrp
7683d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
7684d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
7685d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7686d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
7687d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7688d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
7689d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
7690d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7691d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].red=
7692d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7693d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].red) >> PNGK) & 0xf0)     )  |
7694d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7695d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].red) >> PNGK) & 0xf0) >> 4)) * PNGM;
7696d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].green=
7697d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7698d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].green) >> PNGK) & 0xf0)     )  |
7699d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7700d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].green) >> PNGK) & 0xf0) >> 4)) * PNGM;
7701d337164012450d70d62e71cf4a308a29004f7d57glennrp              image->colormap[i].blue=
7702d337164012450d70d62e71cf4a308a29004f7d57glennrp                  ((((((size_t)
7703d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].blue) >> PNGK) & 0xf0)     )  |
7704d337164012450d70d62e71cf4a308a29004f7d57glennrp                  (((((size_t)
7705d337164012450d70d62e71cf4a308a29004f7d57glennrp                  image->colormap[i].blue) >> PNGK) & 0xf0) >> 4)) * PNGM;
7706d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7707d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7708d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
7709d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
7710d337164012450d70d62e71cf4a308a29004f7d57glennrp
771182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
771282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
771382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
771482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
771582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
771682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
771782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
771882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
771982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.red=
772082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
772182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xe0)     )  |
772282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
772382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xe0) >> 3)  |
772482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
772582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.red) >> PNGK) & 0xc0) >> 6)) * PNGM;
772682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.green=
772782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
772882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xe0)     )  |
772982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
773082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xe0) >> 3)  |
773182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
773282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.green) >> PNGK) & 0xc0) >> 6)) * PNGM;
773382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.blue=
773482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            ((((((size_t)
773582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xe0)     )  |
773682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
773782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xe0) >> 3)  |
773882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            (((((size_t)
773982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
774082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
774182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
774282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7743e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
774482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
774582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
774682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
774782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
774882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
774982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
775082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                exception);
775182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
775282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (r == (PixelPacket *) NULL)
775382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
775482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
775582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
775682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
775782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
775882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
775982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
776082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
776182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
776282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
776382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
776482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
776582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red=
776682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->red) >> PNGK) & 0xe0)    )  |
776782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xe0) >> 3)  |
776882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xc0) >> 6)) * PNGM;
776982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green=
777082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->green) >> PNGK) & 0xe0)    )  |
777182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xe0) >> 3)  |
777282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xc0) >> 6)) * PNGM;
777382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue=
777482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xe0)    )  |
777582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xe0) >> 3)  |
777682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
777782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
777882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r++;
777982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
778082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
778182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
778282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
778382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
778482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
778582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
778682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
778782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
778882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
778982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
779082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7791e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
779282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
779382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
779482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].red=
779582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
779682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xe0)     )  |
779782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
779882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xe0) >> 3)  |
779982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
780082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].red) >> PNGK) & 0xc0) >> 6)) * PNGM;
780182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].green=
780282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
780382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xe0)     )  |
780482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
780582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xe0) >> 3)  |
780682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
780782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].green) >> PNGK) & 0xc0) >> 6)) * PNGM;
780882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              image->colormap[i].blue=
780982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  ((((((size_t)
781082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xe0)     )  |
781182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
781282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xe0) >> 3)  |
781382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  (((((size_t)
781482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
781582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
7816d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7817d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
781882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
7819c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7820c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors == 0 || image_colors > 256)
7821c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7822c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7823c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7824c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
7825c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7826c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.red=
7827770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7828770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xe0)     )  |
7829770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7830770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xe0) >> 3)  |
7831770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7832770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.red) >> PNGK) & 0xc0) >> 6)) * PNGM;
7833c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.green=
7834770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7835770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xe0)     )  |
7836770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7837770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xe0) >> 3)  |
7838770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7839770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.green) >> PNGK) & 0xc0) >> 6)) * PNGM;
7840c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image->background_color.blue=
7841770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            ((((((size_t)
7842770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0)     )  |
7843770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7844770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 2)  |
7845770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7846770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 4)  |
7847770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            (((((size_t)
7848770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp            image->background_color.blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
7849fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7850c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7851c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7852e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
7853fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7854c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
7855c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7856c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
7857c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
7858c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7859c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                exception);
78608d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7861c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (r == (PixelPacket *) NULL)
7862c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
7863c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7864c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
7865c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
786682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
786782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
786882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
786982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
787082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
787182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
787282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
787382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
787482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red=
787582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->red) >> PNGK) & 0xe0)    )  |
787682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xe0) >> 3)  |
787782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->red) >> PNGK) & 0xc0) >> 6)) * PNGM;
787882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green=
787982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->green) >> PNGK) & 0xe0)    )  |
788082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xe0) >> 3)  |
788182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->green) >> PNGK) & 0xc0) >> 6)) * PNGM;
788282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue=
788382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       ((((((size_t) r->blue) >> PNGK) & 0xc0)    )  |
788482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 2)  |
788582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 4)  |
788682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                       (((((size_t) r->blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
788782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
788852a479ca718756af72f96e127f8256499ab68f76glennrp              r++;
7889c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
7890fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7891c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7892c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
7893c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7894c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7895c722dd852e8abe407c2846d39662f7ade9c234deglennrp
7896c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
7897c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
7898c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7899c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
7900c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7901e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
7902c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
7903c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
790452a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].red=
7905770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7906770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xe0)     )  |
7907770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7908770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xe0) >> 3)  |
7909770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7910770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].red) >> PNGK) & 0xc0) >> 6)) * PNGM;
791152a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].green=
7912770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7913770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xe0)     )  |
7914770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7915770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xe0) >> 3)  |
7916770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7917770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].green) >> PNGK) & 0xc0) >> 6)) * PNGM;
791852a479ca718756af72f96e127f8256499ab68f76glennrp              image->colormap[i].blue=
7919770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  ((((((size_t)
7920770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0)     )  |
7921770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7922770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 2)  |
7923770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7924770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 4)  |
7925770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  (((((size_t)
7926770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                  image->colormap[i].blue) >> PNGK) & 0xc0) >> 6)) * PNGM;
7927c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7928c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
7929c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7930c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7931c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
7932fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
7933fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
7934fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7935fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
7936fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
7937fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
7938fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
79390e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
79400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
79410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
79420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
79430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
79450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
79460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
79480e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
79490e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79508d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
79518d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         mng_info->write_png_colortype != (ssize_t) colortype)
79520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
79530b206f5daa453dc1035db5890cabc899736dc2d0glennrp
79540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
79550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
7956fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
7957fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
7958fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
79595a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
79605a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
79615a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
7962fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
79635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
79645a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
7965fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7966fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
7967fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7968fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
7969fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
7970fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7971fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
7972fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
7973fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7974fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           ExceptionInfo
7975fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *exception;
7976fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7977fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           register const PixelPacket
7978fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
7979fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7980fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           exception=(&image->exception);
7981fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7982fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
7983fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
7984fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
7985fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7986fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (q == (PixelPacket *) NULL)
7987fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
7988fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7989fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
7990fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
7991fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 if (q->opacity != TransparentOpacity &&
7992fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->red == ping_trans_color.red &&
7993fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->green == ping_trans_color.green &&
7994fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->blue == ping_trans_color.blue)
7995fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
7996fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
7997fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
7998fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
7999fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8000fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 q++;
8001fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8002fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8003fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8004fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8005fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8006fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8007fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8008fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8009fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Assuming that image->colormap[0] is the one transparent color
8010fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             * and that all others are opaque.
8011fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             */
8012fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
8013fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              for (i=1; i<image_colors; i++)
8014fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                if (image->colormap[i].red == image->colormap[0].red &&
8015fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].green == image->colormap[0].green &&
8016fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                    image->colormap[i].blue == image->colormap[0].blue)
8017fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
8018fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8019fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8020fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8021fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8022fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8023fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8024fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8025fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8026fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8027fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8028fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8029fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8030fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8031fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8032fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8033fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8034fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8035fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8036fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
80373c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
80383c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
80393c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
80403c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8041f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
80423c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
804383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
80440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
80451273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
804752a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
804852a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
804952a479ca718756af72f96e127f8256499ab68f76glennrp    {
805052a479ca718756af72f96e127f8256499ab68f76glennrp      image_info=DestroyImageInfo(image_info);
805152a479ca718756af72f96e127f8256499ab68f76glennrp      image=DestroyImage(image);
805215e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp      (void) ThrowMagickException(&IMimage->exception,
805315e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          GetMagickModule(),CoderError,
805415e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
805515e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "`%s'",IMimage->filename);
805652a479ca718756af72f96e127f8256499ab68f76glennrp#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
805752a479ca718756af72f96e127f8256499ab68f76glennrp      UnlockSemaphoreInfo(ping_semaphore);
805852a479ca718756af72f96e127f8256499ab68f76glennrp#endif
805952a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
806052a479ca718756af72f96e127f8256499ab68f76glennrp    }
806152a479ca718756af72f96e127f8256499ab68f76glennrp
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
8067cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8068cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
80690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
8072cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
80730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
80763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
80770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
80790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
8087cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8100cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8102da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
8103b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8104b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8105b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
81142b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
81192b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
81242b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81254e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
81264e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
81272b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
81330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
81370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
81430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8147e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8149e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8151e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81538640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81558640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81578640fb5e9b1094f35f8beab436f81661b8a99448glennrp
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
81595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
8160dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
816126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
816326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
816426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
8169dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8170dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8174dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8175823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
8176823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->x_resolution+0.5)/2.54);
8177823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
8178823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->y_resolution+0.5)/2.54);
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8180dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8183dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8184823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution+0.5);
8185823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution+0.5);
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8187991d11dd9c33e65872778b81aff1347cd2878154glennrp
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8190dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
8191dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
8192dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8194991d11dd9c33e65872778b81aff1347cd2878154glennrp
8195823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
8196823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8197823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
8198823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
8199823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
8200991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
820226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8204a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
820526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
820626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
8207a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8209a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
8210a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
8211a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
8212a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
8213a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
8214a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
82150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8216a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
8217a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
82180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8219a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
8220a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
82210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8222a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
8223a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
82240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8225a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
8226a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
82270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8228a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
8229a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
82300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8231a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
8232a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
82330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
82340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
82363b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
82373b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82383b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
82393b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
82403b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82413b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
82423b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
82430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
824526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
82520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82531273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8256fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
82570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
82580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
82608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
82618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
82620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
82640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
82650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
82660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
82670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
82690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
8271f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
82720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
82740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
82750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
82760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
82770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
82780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
82790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
82810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
82830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
82850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
82882b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
82908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
82918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
82925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
829358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
82948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
82950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
82960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
82970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
82980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
82998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
83028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
83030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83052cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
83068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
83070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
83090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
83100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
83138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
83140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83151273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
83164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
83171273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
83181273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
83191273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
83201273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
83214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
83224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
83234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
83240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
83264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
83280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
83325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
83385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
83440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
83480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
83505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
83522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
83538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
83557c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
83567c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
83577c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83587c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83617c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
83660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8367d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
83688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
83690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8370d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8376d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83825aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
83835aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
83845aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
83855aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
83867c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
83877c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
83887c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83905aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
83918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
83925aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
83935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
83945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
83955aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
83965aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
83970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83980b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
83995aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
84015aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84025aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
84045aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
84055aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
84065aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84075aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84085aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
84095aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84105aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
84120b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84135aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84145aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
84155aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84165aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
84180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
84195aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
842326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84248640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
842526c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
84265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
84270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
84280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
84290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
84300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
84310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
84320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8434d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
8435d6bf1617e99df0272b231855a933a74e99b6578fglennrp
84365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84388d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
84398d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84418640fb5e9b1094f35f8beab436f81661b8a99448glennrp
84425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
844435ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
84455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
84460f111984738842d27d04aed2a3f823d82a943506glennrp
84470f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
84480f111984738842d27d04aed2a3f823d82a943506glennrp           {
84490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
8450c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              (void) ThrowMagickException(&image->exception,
84510f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
8452c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                "image has 0 colors", "`%s'","");
84530f111984738842d27d04aed2a3f823d82a943506glennrp           }
84540f111984738842d27d04aed2a3f823d82a943506glennrp
845535ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
84565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
8457d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8459d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
8460d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
8461d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8462d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
84630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8464d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8465d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
8466d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
84670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8468d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
8469d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
84725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
84732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8477e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
84780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8480e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
84810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8483e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
84840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
84878640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
84888640fb5e9b1094f35f8beab436f81661b8a99448glennrp
84898640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8490e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
84913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
849358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
84964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
84977c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
84987c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
84997c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
85002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85017c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
85027c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
85037c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
85042b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
85064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
85084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
85094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
85114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
85124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
8513a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
85144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
85157c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
85167c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
85177c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
85184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
85214f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85224f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
85231273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp                mask;
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
85260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
85284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
85290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
85314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
85320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
85344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
85350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
85374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
85380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
85404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
85410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
85434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
85440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
85464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
85470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
85494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
85504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
85510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
85530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
85554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
85584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
8560fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
8561fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
8562fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
8563fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
8564fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
85654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85662b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
85684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85697c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
85707c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
85710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
85734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
85744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
85754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
85764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
85774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
85784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
85794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
85814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
85824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
85855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
85865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
85875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
85885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85928640fb5e9b1094f35f8beab436f81661b8a99448glennrp
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
85940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85952e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
85970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
859839992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
86008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
86018d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
860335ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
86040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
86069c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
86070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86087c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
86114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
86134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
86144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
86154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
86164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
86184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
86194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
86204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
86250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8626272f23a9dfc9a9104b8cd180c97afba2d20c6683cristy        if ((image_colors == 0) || ((ssize_t) image_colors-1 > MaxColormapSize))
8627f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
86280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
86305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
86310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
86355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
86395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
86400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
864135ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
8642bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
86435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
86480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
86521a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8658bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
86694bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
86722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
86749c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
86750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
86779c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
86780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
86809c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86832b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
86860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
86880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
869117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
869217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
86985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
86990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
870058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87029c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
87030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87059c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87069c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8711bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87183b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
872098156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
8721f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
87220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
872339992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8727d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8729befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8730befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8731befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
87325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8733befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
87340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8735befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
87365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
87400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
874158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
87420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
87430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8744d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8745d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
87460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8748d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8749d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
87520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
87530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8754d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
87550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8756c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8757c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8758c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8759c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8760c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8761d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8762d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8763d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8764d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8765d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8766d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8767d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
87680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
87690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8775c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
87780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
87824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
87834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
87854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
87864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
87874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
87884f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
87894f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
87905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
87915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
87925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
87935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
87944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
87954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
87964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
87974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
87994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88064383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
88074383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
88082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
88125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
881835ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
881935ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
882035ef824baa82511126ff0072ae30eee0da9c05a3cristy
882122ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
882426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8826a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88313c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
88323b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8833991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
883426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
88375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
883917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
884026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
884126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
88421273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
884317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
884417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
884517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
884617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
884717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
884817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
884917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8850a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8851a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
885217a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
885317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
885417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
885517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
88563b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
88570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
88580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
88600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8861a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
886213d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8863a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
88640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
88653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
88663b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
88670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
88680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
88700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
88710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
88720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
88730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8874a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
887517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8876d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
88773c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
88783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
88793b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88803b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
88813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
88823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
888317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
888426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
888517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
88940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
88960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
88990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
89000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
89020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
89060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
89080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
89110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
89180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
89220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
89310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89392b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
89460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89552b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
89618640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
89620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89638640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
89648640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
89660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89678640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
89688640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
89695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
89718640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
89720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89738640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
89748640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
89750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89852b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8989823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if ((ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse) &&
8990823b55c200d7fc1818ab539b036a9c24feaecda8glennrp     (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
8991c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
8992c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
8993c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8995c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
89960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8997c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
8998c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
8999c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
9000c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
9001c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
900226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
9003c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
9004c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
9005c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
9006c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
9007e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
9008c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
9009e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
9010e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
9011e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
9012c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
9013c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
901426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
90150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9016c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9018c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
9019c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
9020cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
9021c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
9022c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
9023c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
9024c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
9025c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
90260b206f5daa453dc1035db5890cabc899736dc2d0glennrp
9027c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
9028c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9029c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
90300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9031c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
9032c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
904026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
904126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
904226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
904326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
904426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
904526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
904626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
904726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
90480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
904926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
9050cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
9051cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
90520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
905326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
905426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
905526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
905726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
90585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90612cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
90622cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
906326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
906426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
90743b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
907726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
90782b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
907926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
908126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
908226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
908326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
908426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
908526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
908626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
908726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
908826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
908926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
909026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
909126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
909226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
909326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
909426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
909526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
909626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
909726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
909826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
909926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
910026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
910126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
910226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
910326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
910426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
910526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
910626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9108dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
91095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9116d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
91198d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
91215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
91222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
91235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
91245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
91260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
91288d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91320e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
91330e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
91345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
91365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
9137991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
91380e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
91430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
91440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
91460e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
91470e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
91535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91550e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
91615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91653bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
916958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
91740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9175b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
9176b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9177b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91800e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
9181e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
9182991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
9183c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
9184991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
9185c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
9186c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9187c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
9188c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
9189e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
9190e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
91965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
91975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
91985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
91995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
920039992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
920139992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
9202f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
92030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92043b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
920539992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
92068640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
92070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
9208d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
92090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9210d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
9211d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
9215d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
92170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
92180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9219d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
92200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
92210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
92240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
922539992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
922639992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
922739992b4dd9b12ef752d55b8e402c069698851f72glennrp
922826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
922926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
923026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
923126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
923226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
9233991d11dd9c33e65872778b81aff1347cd2878154glennrp
923426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
9235dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
923626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
923726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
923826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
923926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
924026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
924126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
9242823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
9243823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
9244823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
9245823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9246823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
9247823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9248823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
9249823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
9250823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9251823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
9252823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
9253823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9254823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
9255823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
9256823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
925726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9258dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9259dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9260dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
92614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
9262dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
926326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
926426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
926526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
926626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
9267dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
926826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
926926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
927026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
927126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
927226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9273dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9274dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
9275dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9276da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
9277da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
9278da8f3a7bfddac2680a3069a490db541e7944edafglennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
9279da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
9280da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
9281da8f3a7bfddac2680a3069a490db541e7944edafglennrp
9282da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
9283da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
9284da8f3a7bfddac2680a3069a490db541e7944edafglennrp
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
9286991d11dd9c33e65872778b81aff1347cd2878154glennrp
928739992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
9288991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
92893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
92900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
92910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
92930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
9294991d11dd9c33e65872778b81aff1347cd2878154glennrp
92950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
92960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
92970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
92980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
92990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
9300991d11dd9c33e65872778b81aff1347cd2878154glennrp
93010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
93020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
93040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
93050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
93060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
93070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
93090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
93100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9311c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
93120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
93130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
93140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
93150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
93160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
93170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
9318991d11dd9c33e65872778b81aff1347cd2878154glennrp
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
9320cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
9321da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
9323991d11dd9c33e65872778b81aff1347cd2878154glennrp
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
9325cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
932726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
93304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
933126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
933226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
933326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
933426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
933526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
933626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
933703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
933826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
933926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
934026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
934126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
934226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
934326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
93479c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
93499c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
9358b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
9359b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
93607202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9362b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
9364b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9366b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
9367b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
9368b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9370b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
9372b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9374b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
9375b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
93783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9380b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9381b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
93820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9383b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9384e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9386cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
9387cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
93880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9389cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
93910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
9407cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
9408cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9410cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9412da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
9413b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
9414b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
9415b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9418ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
9419ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
9420ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
94248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
94268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
94278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
94298d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
94308d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
94350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9442bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
94453b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94463b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
9447a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
94490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
94520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9456cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,GrayQuantum,ping_pixels,&image->exception);
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
9462bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
9463cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
94670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9471cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,RedQuantum,ping_pixels,&image->exception);
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
94730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
9475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
9476cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
94780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94793b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
9480b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9481b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
94820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9483cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
949858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
94995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
95008d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
95040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
95112cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
95178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9519cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,GrayQuantum,ping_pixels,&image->exception);
95202cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9523cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RedQuantum,ping_pixels,&image->exception);
95242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
95268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
9531b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
95323b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9533b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
95352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9537cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
9538b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
95392cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95403b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
9541b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
95432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9544cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
95488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
95498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
95508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
95518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
95528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
95538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
95548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
95550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
95600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
95648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
95658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
95668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
95678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
9568b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
95698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
95708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
95712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
95738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
95742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
95768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
95778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
95788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9579cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,RedQuantum,ping_pixels,&image->exception);
95802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
95828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9583cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,GrayQuantum,ping_pixels,&image->exception);
95848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
95852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
95878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
95888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9589cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
95908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
95912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
95938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
95958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
95962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
95988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9599cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBAQuantum,ping_pixels,&image->exception);
96002cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
96028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9603cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBQuantum,ping_pixels,&image->exception);
96042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96053b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9606b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
96082cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9609cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
9610b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
96118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96148bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
96158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
96168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
96178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
96188bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
96198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
96208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
96228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
96242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
96268bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
96278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
96308640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
96318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
96328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
96342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9635770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
9636770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                   &image->exception);
96372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
96398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
964244757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
96434bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
96444bf89731a90c6e03598950223e19e7be7b95d630glennrp
964544757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9646cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                       quantum_info,GrayQuantum,ping_pixels,&image->exception);
964744757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
96482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
96528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
96542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9656cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
9657d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
96588bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
96618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
9662179d075d718a6da568c3600b7e6b159b8a293b41glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
96635eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      quantum_info,IndexQuantum,ping_pixels,&image->exception);
96642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96655eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
96665eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
96675eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96681a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
96695eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
96705eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96715eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
96725eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
96735eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
96748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
9675cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
96768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
96778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
96808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
96818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
96828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
96838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96848640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
96853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
96888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9689b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
9690b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9695b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
96960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9698e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
96990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9701e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
97020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
97110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
97163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
97200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9727823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
97283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
972926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
973026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
973126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
973226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
973326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
973426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
97352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
973626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
9737823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (ping_exclude_pHYs != MagickFalse       ||
9738147bc91f6859c598c4f57b6a162111b2f63614d9glennrp          LocaleNCompare(property,"png:",4) != 0 ||
9739823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
9740823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"units") != 0)
974126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
9742c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
9743c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
9744c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
9745c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
9746c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
9747c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
97482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9749c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
9750c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
97512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9752c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
9753c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
97542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9755c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
975626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
9757c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
9758c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
9759c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
9760c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
976126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
97622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9763c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
9764c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
9765c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9766c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
9767c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9768c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9769c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
9770c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
9771c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9772c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
9773c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
9774c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
977526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
977626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
977726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
9781cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
97860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
97880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
97925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
97935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
98023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
980303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
98043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
98123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
98133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
98145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
98175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
98183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
98213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
98263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
9829c70af4ac292f8db9a1ab488318912894d412cb8cglennrp     (void) ThrowMagickException(&image->exception,GetMagickModule(),
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
9831c70af4ac292f8db9a1ab488318912894d412cb8cglennrp       "`%s'",image->filename);
98320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9839cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9842cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
98433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9845da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (ping_have_blob != MagickFalse)
9846b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9847b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9848b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9849b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9850b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9851b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9852b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9853b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9854b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9855b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9856b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
98600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98995a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
99005a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
99035a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
99045a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
9905e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
9906e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               3-3-3-1, or  3-3-2-1 palette.
9907e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
9908e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
9909e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
99105a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
99115a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
99135a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
99145a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
99155a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
99195a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
99205a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
99215a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
99225a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
99235a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
99280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
99295a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
99305a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9935bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9936bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9937bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
99565a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
99575a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
99585a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
99625a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
99635a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%   or transparency limitations.
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
9980bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
9981bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
9986bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9988bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99903241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
99910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
9992d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
99930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
99940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
99950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
9996cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
99970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
9998d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
9999d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
10000d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
10001d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
10002d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
10003d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
10004d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
100050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
100083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1001221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1001321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1001421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1002421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
100255c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
100265c7cf4e469a4dad7e277783749155932252c52dfglennrp
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10035fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
100383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1004073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
100410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
10050a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
100523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100619c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
100629c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
100639c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100689c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
100699c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
100709c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
100710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100729c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
100739c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
100740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100759c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
100769c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
100770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100789c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
100793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100839c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
100849c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
100859c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
100860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100879c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
100889c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
100890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100909c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
100919c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
100920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100939c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
100943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
100978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
100983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
101019c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
101020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101049c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
101050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101079c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
101080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
101109c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
101110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
101139c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
101140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10115bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10116bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10117bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10118bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
10119bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10120bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101229c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10123bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
101270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
101329c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
101330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101359c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
101360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
101389c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
101390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101419c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
101420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
101449c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
101450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10146bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10147bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10148bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10149bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
10150bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10151bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101539c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10154d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
101580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101590dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
101600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
101610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
101630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
101640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
101650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
101660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
101670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
101690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
101710e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
101720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
101730dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
101740dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
101750dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
101760dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * appear in the "include-chunk" list.
101770e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101780e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
101790e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
101800e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
101810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
101830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
101840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
101850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
101870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
101880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
101900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
101910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
101920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1019326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1019426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
1019526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1019626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1019726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1019826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1019926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1020026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1020126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1020226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
10203a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1020426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1020526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1020626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1020726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1020803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1020903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
102105c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
102115c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
102125c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10213acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102145c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
10215acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10216acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10217acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
10218acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
102195c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10220acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102215c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1022226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10223acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10224acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
10225acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10226acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1022703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1022803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1022926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1023003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1023103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1023226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1023303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1023426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1023503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
102362cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
102372cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
102382cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102392cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
102402cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
102412cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102422cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
102432cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1024403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1024503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1024603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1024703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1024803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1024903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1025003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1025103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1025203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1025303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
1025403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1025503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1025603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1025703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1025803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1025903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1026003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1026103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
10262a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1026303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1026403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1026503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1026603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1026703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
102682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1026903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1027003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1027103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1027203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
1027303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1027403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1027503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1027603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1027703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1027803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1027903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1028003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
10281a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1028203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1028303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1028403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1028503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
102862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1028703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1028803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
102892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1029003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1029103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
102922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1029303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1029403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
102952cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1029603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1029703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
102982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1029903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1030003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
103012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1030203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1030303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1030403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1030503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
103062cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1030703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1030803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1031003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1031103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
103122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1031303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1031403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
103152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10316a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10317a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
103182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1031903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1032003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
103212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10322a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10323a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
10324a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1032503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1032603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
103272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1032803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1032903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
103302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1033203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
103332cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10335ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1033626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1033726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
103385c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
103395c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
103405c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10341acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103425c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
10343acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10344acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10345acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
10346acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
103475c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10348acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103495c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1035026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10351acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10352acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
10353acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10354acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1035503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1035603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1035703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1035803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1035926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1036003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1036126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1036203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
103632cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
103642cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
103652cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103662cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
103672cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
103682cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103692cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
103702cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1037103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1037203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1037303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1037403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1037503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1037603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1037703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1037803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1037903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
1038003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1038103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1038203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1038303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1038403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1038503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1038603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1038703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
10388a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1038903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1039003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1039103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1039203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1039303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
103942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1039503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1039603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1039703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1039803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
1039903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1040003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1040103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1040203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1040303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1040403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1040503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1040603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
10407a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1040803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1040903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1041003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1041103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104122cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1041303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1041403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
104152cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1041603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1041703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
104182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1041903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1042003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
104212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1042203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1042303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104242cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1042503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1042603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
104272cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1042803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1042903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1043003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1043103812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
104322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1043303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1043403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1043603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1043703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
104382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1043903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1044003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
104412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10442a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10443a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
104442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1044503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1044603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
104472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10448a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10449a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
10450a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1045103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1045203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
104532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1045503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
104562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1045803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
104592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10461ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1046226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1046326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1046403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1046526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1046626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1046726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
1046826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1046926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1047126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1047226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
1047426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1047526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1047726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1047826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1048026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1048126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1048226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1048326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1048426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1048526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1048626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1048726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1048826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1048926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1049026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1049126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1049226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1049326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1049426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1049526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1049626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1049726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1049826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1049926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
10500a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
10501a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10502a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1050326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1050426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1050526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1050626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1050726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1050826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1050926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1051026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1051226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1051326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10514b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
105153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10516b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
105190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
105220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
105253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
105333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
105343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
105363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1053903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
105413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
105443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
105533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10556bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
105583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
10560fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
105850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
105900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
105920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
105950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
105990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
106010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
106083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
106090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
106120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
106150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
10671f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
106730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10676e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
10677e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1068903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
106904e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
106914e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10705f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
107060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10708f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
107090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
107120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
107150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
107180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
107210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
107240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
107270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
107300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
10736cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
10760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1076203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1078303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
107840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10786e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10787cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10788e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
107890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10791e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10792cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10793e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
107940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1080703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1080835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1082403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1082635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1082735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1082935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1083035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1083235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1083335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
108343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1083535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1083635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
108373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
108393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1084903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1085235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
108540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1085535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
108570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1086535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
108670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1086835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
108700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
108753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1087635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1087735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1089203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10893bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10894bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
108973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
109003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
109023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1090303812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
109083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
109133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
109153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10916bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
109183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10919bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10925e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10926f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
109350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10939bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1094003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
109413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
109423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
109433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10950e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10951e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10961e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
10962bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1096403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
109663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
109673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
109793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
109833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
109873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
109883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
109933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
109993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11000e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
11001e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
110050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
110130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
110150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11019e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
11020e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11023e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
11027bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1102903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
11040cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1104503812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
110483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
110520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
110613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
110633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
110653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
110693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
110713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
110733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
110753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
110773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1108721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1108803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
110933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
111003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11102fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1111173bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1114521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1114803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1114903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1115003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11168bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
111723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11181bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
111833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11185d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
111873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
111893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
111933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
111963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
111973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
111983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11199fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1120873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
112163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
112263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
112293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
112333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
112490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11251e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
112520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11260e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
112610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11263e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
112640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
112680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
112720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
112760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
112783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
112800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11283e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
112840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
112880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
112973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
113003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
113083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
113093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
113113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
113123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
113163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
113203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
113233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
113283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
113313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
113323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
113333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
113343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
113363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
113373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
113383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
113463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
113473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
113510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
113550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
113580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
113610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
113663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
113670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
113700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
113720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
113753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
113760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
113840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
113993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
114033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
114040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
114063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
114070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
114093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
114110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
114153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
114160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
114183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
114203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
114243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
114273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
114283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
114323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
114333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
114343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
114353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
114393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
114403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
114423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
114433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
114443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
114453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
114463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
114473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
114483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
114513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
114523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
114540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
114593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
114613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
114643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
114680261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
11469d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
11470d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
11471d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
11472d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
11473d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
11474d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
11475d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
11481cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
11482cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
114850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
114880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
114910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
114980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
115083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
115103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
115113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1151203812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
115134e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
115144e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
115153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
115163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
115173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
115183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
115193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
115203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
115250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
115283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
115340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
115413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
115460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
115493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
115550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
115583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
115613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
115623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
115633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
115643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
115663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
115673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
115693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
115713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
11573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1157403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
115753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
115763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
115773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
115813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
115823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
115843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
115853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
115863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
115873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1158803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
115893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
115903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
115930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
115960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
115990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11603e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
11604e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
116050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11608e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
116090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11612e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
116133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
116193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
116223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1162803812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
116290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
11631e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11632cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11633e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
116340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
11636e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11637cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11638cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
116390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
116413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
116423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
116433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
116463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
116483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
116503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
116513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
116523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
116533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1165403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1165535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
116573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
116583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
116643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
116673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
116683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
116693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1167003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
116713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1167235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1167335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1167535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1167635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
116773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1167835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1167935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
116803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1168135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1168235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
116833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
116843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
116853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
116863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
116893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
116923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
116943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1169503812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
116960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
116983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1169935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
117003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
117010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1170235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
117033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
117040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
117063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
117093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
117113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1171235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
117133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
117140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1171535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
117170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
117193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
117223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1172335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1172435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
117253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
117263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
117293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
117303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
117323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
117333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
117343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
117353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
117363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
117373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
117383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
117393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
117403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
117423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1174303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
117443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
117453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
117463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
117473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
117493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
117503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
117513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
117523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
117553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1175603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
117573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
117593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
117633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
117643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
117653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
11767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
117683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
117713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
117743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1177603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
117770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11778bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
117803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
117833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
117840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
117973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
117993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
118003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
118043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
118053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
118063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
118073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
118123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
118143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
118163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
118173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
118183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
118193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11822bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
118243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
118263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
118273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1182803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
118290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
118323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
118333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
118343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
118360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
118393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
118403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
118413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
118423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
118443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
118483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11849bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
118503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
118513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
118563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
118573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
118593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
118613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
118623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
118653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
118663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
118683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1186903812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
118703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
118723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
118743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
118763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
118773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
118783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
118803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
118833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
118863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
118893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
118963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1189803812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
118993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
119043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
119073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
119093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1191003812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
119133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
119143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
119193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
119224e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
119373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
119482f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11949b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
119502f2e514554975d510c88df54de98c6cdc1080f1cglennrp
119512f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
119522f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
119532f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
119542f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
119552f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
119562f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
119572f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
119582f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
119592f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
119602f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
119612f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
119622f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
11963a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
119642f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
119652f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
119662f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
119672f2e514554975d510c88df54de98c6cdc1080f1cglennrp
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
119723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
119733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
119743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
119753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
119783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
119813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
119830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
119860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
119880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
119903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
119913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
119923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
119933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
119943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
119953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
119963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
119973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1199803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
119993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
120003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
120013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
120043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
120063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
120070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
120093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
120100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
120123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12013d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1201439992b4dd9b12ef752d55b8e402c069698851f72glennrp
120153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
120163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
120200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1202439992b4dd9b12ef752d55b8e402c069698851f72glennrp
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
120263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12029d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12031