png.c revision 3241bd0c43e56612fc7aa006a0d30333dacbb51a
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"
455a2ca481ab4ff6751bba842263739966e53441aacristy#include "magick/attribute.h"
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h"
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h"
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h"
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color.h"
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color-private.h"
514ccd4c0b8623aa47f1c10dd366666799e5957c3ccristy#include "magick/colormap.h"
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/enhance.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/geometry.h"
58f2e1166e90de2dfe2e6a2aed7cd5f73640f34a7acristy#include "magick/histogram.h"
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/layer.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h"
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/profile.h"
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/property.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantize.h"
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/resource_.h"
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/semaphore.h"
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/static.h"
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/statistic.h"
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h"
80f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy#include "magick/string-private.h"
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/transform.h"
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/utility.h"
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
84286a6355c4544b794da2b6df973faad07c69e541glennrp
857ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
867ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
87faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
887ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
90991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
91faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
92faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
93faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
94faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
95286a6355c4544b794da2b6df973faad07c69e541glennrp
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1153241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp#define PNG_BUILD_PALETTE   /* This works as of 6.6.6 */
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *png_semaphore = (SemaphoreInfo *) NULL;
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrptypedef struct _UShortPixelPacket
24505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp{
24605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  unsigned short
24705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    red,
24805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    green,
24905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    blue,
25005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    opacity,
25105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    index;
25205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp} UShortPixelPacket;
25305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
274bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39835ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
430bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4700c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4730c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
4800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
4820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
4838640fb5e9b1094f35f8beab436f81661b8a99448glennrp  LosslessReduceDepthOK(Image *image)
4840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
4850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    MagickBooleanType
4860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      ok_to_reduce=MagickFalse;
4870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4880c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    /* Reduce bit depth if it can be reduced losslessly from 16 to 8.
4890c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * Note that the method GetImageDepth doesn't check background
4900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * and doesn't handle PseudoClass specially.  Also it uses
4910c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * multiplication and division by 257 instead of shifting, so
4920c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     * might be slower.
4930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp     */
4940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4950c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    if (image->depth == 16)
4960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
4970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        const PixelPacket
4990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
5000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
5020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          (((((size_t) image->background_color.red >> 8) & 0xff)
5038640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.red & 0xff)) &&
5040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.green >> 8) & 0xff)
5058640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.green & 0xff)) &&
5060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp           ((((size_t) image->background_color.blue >> 8) & 0xff)
5078640fb5e9b1094f35f8beab436f81661b8a99448glennrp          == ((size_t) image->background_color.blue & 0xff))) ? MagickTrue :
5088640fb5e9b1094f35f8beab436f81661b8a99448glennrp          MagickFalse;
5090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
5110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
5130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5140c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
5150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5168640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
5178640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    8) & 0xff)
5188640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5208640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5228640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].blue & 0xff)) &&
5230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) image->colormap[indx].opacity >> 8) & 0xff)
5248640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  == ((size_t) image->colormap[indx].opacity & 0xff))) ?
52513d07043243e0c8c151aad7db5240b75e76ca281cristy                  MagickTrue : MagickFalse;
5260c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5270c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
5320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
5330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
5350c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
5360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
5380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
5390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
5410c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
5420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5440c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              if (p == (const PixelPacket *) NULL)
5450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
5460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
5470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
5490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
5510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5528640fb5e9b1094f35f8beab436f81661b8a99448glennrp                ok_to_reduce=((
5538640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->red >> 8) & 0xff) ==
5548640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->red & 0xff)) &&
5550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->green >> 8) & 0xff) ==
5568640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->green & 0xff)) &&
5570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ((((size_t) p->blue >> 8) & 0xff) ==
5588640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->blue & 0xff)) &&
5598640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((!image->matte ||
5608640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  (((size_t) p->opacity >> 8) & 0xff) ==
5618640fb5e9b1094f35f8beab436f81661b8a99448glennrp                  ((size_t) p->opacity & 0xff))))) ? MagickTrue : MagickFalse;
5620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5630c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5660c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                p++;
5670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5688640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
5690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
5700c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
5710c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5720c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5730c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
5740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5768640fb5e9b1094f35f8beab436f81661b8a99448glennrp                "  OK to reduce PNG bit depth to 8 without loss of info");
5770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5780c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
5790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
5810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
5820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
5830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
584e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
585e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
5860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
587e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
588e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
589e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
590e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
5910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
592e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
593e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
5940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
595e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
596e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
5970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
598e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
599e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
6000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
601e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
602e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
603e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
604e610a071534e448c46460a5aa39ede33bf56b329glennrp}
605e610a071534e448c46460a5aa39ede33bf56b329glennrp
606e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
607e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
6080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
609e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (png_intent)
610e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
611e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
612e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
6130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
614e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
615e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
6160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
617e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
618e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
6190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
620e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
621e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
6220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
623e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
624e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
625e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
626e610a071534e448c46460a5aa39ede33bf56b329glennrp}
627e610a071534e448c46460a5aa39ede33bf56b329glennrp
628bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6350c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6430c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
644dbb105fc25903e800273f7e980c0553060858a68glennrp
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
650dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
656dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
657dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
658dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
660dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
665bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
667dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
668dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
673dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
674dbb105fc25903e800273f7e980c0553060858a68glennrp
675dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
677dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
678dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
679dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
680dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
682bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
686dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
687dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
688dbb105fc25903e800273f7e980c0553060858a68glennrp    {
689dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
690dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
691dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
692dbb105fc25903e800273f7e980c0553060858a68glennrp    }
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
694dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
695dbb105fc25903e800273f7e980c0553060858a68glennrp}
696dbb105fc25903e800273f7e980c0553060858a68glennrp
697dbb105fc25903e800273f7e980c0553060858a68glennrp/*
698dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
699dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
700dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
701dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
702dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s M o n o c h r o m e                                         %
703dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
704dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
705dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
706dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
708dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
709dbb105fc25903e800273f7e980c0553060858a68glennrp%   and is more accurate.                                                     %
710dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
711dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712dbb105fc25903e800273f7e980c0553060858a68glennrp*/
713dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsMonochrome(Image *image)
714dbb105fc25903e800273f7e980c0553060858a68glennrp{
715dbb105fc25903e800273f7e980c0553060858a68glennrp  register const PixelPacket
716dbb105fc25903e800273f7e980c0553060858a68glennrp    *p;
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
718dbb105fc25903e800273f7e980c0553060858a68glennrp  register ssize_t
719dbb105fc25903e800273f7e980c0553060858a68glennrp    i,
720dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
721dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
722a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
723dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image != (Image *) NULL);
724dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image->signature == MagickSignature);
725a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if (image->debug != MagickFalse)
726dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
727dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
728a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp    {
729dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
730dbb105fc25903e800273f7e980c0553060858a68glennrp      {
731dbb105fc25903e800273f7e980c0553060858a68glennrp        if ((IsGray(image->colormap+i) == MagickFalse) ||
732dbb105fc25903e800273f7e980c0553060858a68glennrp            ((image->colormap[i].red != 0) &&
733dbb105fc25903e800273f7e980c0553060858a68glennrp             (image->colormap[i].red != (Quantum) QuantumRange)))
734dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
735dbb105fc25903e800273f7e980c0553060858a68glennrp      }
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
738dbb105fc25903e800273f7e980c0553060858a68glennrp  for (y=0; y < (ssize_t) image->rows; y++)
739dbb105fc25903e800273f7e980c0553060858a68glennrp  {
740dbb105fc25903e800273f7e980c0553060858a68glennrp    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
741dbb105fc25903e800273f7e980c0553060858a68glennrp    if (p == (const PixelPacket *) NULL)
742dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
743dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
7540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
760d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
878d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
879bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
901a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
909a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
926e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
927e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
929d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
935d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1049e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1050e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1078bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
10940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
10970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
11550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1169bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1181bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
12030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
12080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1221bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1223bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
12360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
12400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
12540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
12570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
12600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
12630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1277bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1278bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1296bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
12988182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
12998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
13000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13108182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
13250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1329faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1331faa852bad40107edae19405e76a299057668d795glennrp#else
1332faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1333faa852bad40107edae19405e76a299057668d795glennrp#endif
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
13430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1347cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
13480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
13620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
13650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1425f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
14260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
14290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
14390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
14510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
14680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
14770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
14800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
15160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1572faa852bad40107edae19405e76a299057668d795glennrp    pass,
1573faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1574faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1575faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1576faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1577faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1578faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
158305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  UShortPixelPacket
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1586faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1587faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1588faa852bad40107edae19405e76a299057668d795glennrp
1589faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1590faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1591faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1592faa852bad40107edae19405e76a299057668d795glennrp
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1603faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1604faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1605faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1606faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1607faa852bad40107edae19405e76a299057668d795glennrp
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1614bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
16215c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
163139992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1650f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
165325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
165961b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
166061b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
166161b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
166261b4c957269727a0a2526edc2331881da8346100glennrp    {
166361b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
166461b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
166561b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
166661b4c957269727a0a2526edc2331881da8346100glennrp    }
166761b4c957269727a0a2526edc2331881da8346100glennrp#  endif
166861b4c957269727a0a2526edc2331881da8346100glennrp#endif
166961b4c957269727a0a2526edc2331881da8346100glennrp
167061b4c957269727a0a2526edc2331881da8346100glennrp
1671ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
16890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
16970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
17050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1706faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1713f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17207b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
17217b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
17227b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
17237b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
17240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1730faa852bad40107edae19405e76a299057668d795glennrp
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1766991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1767991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1768991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1782991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1786faa852bad40107edae19405e76a299057668d795glennrp
1787faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1788faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1789faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1790faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1791faa852bad40107edae19405e76a299057668d795glennrp
1792faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1793faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1794faa852bad40107edae19405e76a299057668d795glennrp
1795faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1796faa852bad40107edae19405e76a299057668d795glennrp
1797faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1799faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1800faa852bad40107edae19405e76a299057668d795glennrp        {
1801faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1802faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1803faa852bad40107edae19405e76a299057668d795glennrp        }
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1805faa852bad40107edae19405e76a299057668d795glennrp
1806faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1808faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1812e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1813e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
18140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1817faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
18180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1821faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
18220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1825faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1828faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1829faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1865e610a071534e448c46460a5aa39ede33bf56b329glennrp      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1866e610a071534e448c46460a5aa39ede33bf56b329glennrp        mng_info->global_srgb_intent);
18670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1870e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1871e610a071534e448c46460a5aa39ede33bf56b329glennrp          intent);
18720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1875e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1883faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1884faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1885faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
18860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1895faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1896faa852bad40107edae19405e76a299057668d795glennrp    {
1897faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1898faa852bad40107edae19405e76a299057668d795glennrp        {
1899faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1900faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1901faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1902faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1903faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1904faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1905faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1906faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1907faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1908faa852bad40107edae19405e76a299057668d795glennrp        }
1909faa852bad40107edae19405e76a299057668d795glennrp    }
19100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1911faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1928e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1930e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1931e610a071534e448c46460a5aa39ede33bf56b329glennrp         PNG_RenderingIntent_from_Magick_RenderingIntent(
1932e610a071534e448c46460a5aa39ede33bf56b329glennrp         image->rendering_intent));
1933faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1934faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1935faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1936faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1939faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
19430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1947e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1948e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1952faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1953faa852bad40107edae19405e76a299057668d795glennrp    {
1954faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1955faa852bad40107edae19405e76a299057668d795glennrp        {
1956faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1957faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1958faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1959faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1960faa852bad40107edae19405e76a299057668d795glennrp        }
1961faa852bad40107edae19405e76a299057668d795glennrp    }
1962faa852bad40107edae19405e76a299057668d795glennrp
1963faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19760881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19770881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19780881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1989e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1990e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1993faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2004faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
20100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2011faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2028faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2037faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2038faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2061faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2062faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2065faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20742cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2076faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2077faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2078faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20812cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20832cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
20842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
20852cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20862cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
20872cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
20892cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
20902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
20912cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
20920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
20942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
20950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
20972cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
20980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20992cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
21002cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
21010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21022cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
21032cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
21042cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21052cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
21062cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
21072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
21082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
21112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
21130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21152cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
21162cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
21182cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2120faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2123faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2126faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2128f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
21292cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21312cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2132e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2133e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2134e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2135e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
2143faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
215135ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
215235ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
215335ef824baa82511126ff0072ae30eee0da9c05a3cristy
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2158f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2160faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2161faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2162faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2163faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2164faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2165faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2171faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
217605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.red= (unsigned short)(ping_trans_color->red);
217705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.green= (unsigned short) (ping_trans_color->green);
217805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.blue= (unsigned short) (ping_trans_color->blue);
217905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.opacity= (unsigned short) (ping_trans_color->gray);
218005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2181faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21830f111984738842d27d04aed2a3f823d82a943506glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
21840f111984738842d27d04aed2a3f823d82a943506glennrp              if (ping_bit_depth < MAGICKCORE_QUANTUM_DEPTH)
21850f111984738842d27d04aed2a3f823d82a943506glennrp#endif
218605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              transparent_color.opacity=(unsigned short) (
21870f111984738842d27d04aed2a3f823d82a943506glennrp                  ping_trans_color->gray *
218805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                  (65535L/((1UL << ping_bit_depth)-1)));
21890f111984738842d27d04aed2a3f823d82a943506glennrp
219005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
219105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              else
219205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity=(unsigned short) (
219305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                    (ping_trans_color->gray * 65535L)/
219405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                   ((1UL << ping_bit_depth)-1));
21950f111984738842d27d04aed2a3f823d82a943506glennrp#endif
21960f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
21970f111984738842d27d04aed2a3f823d82a943506glennrp              {
21980f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21990f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
22000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22010f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22020f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
22030f111984738842d27d04aed2a3f823d82a943506glennrp              }
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2213faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2218faa852bad40107edae19405e76a299057668d795glennrp
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2220faa852bad40107edae19405e76a299057668d795glennrp
2221faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2222faa852bad40107edae19405e76a299057668d795glennrp
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2227bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2232faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2233faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2244faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2245faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2246faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2247faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2248faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2250befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2251befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2252befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2254befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2255befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2263faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2272bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2288faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2298bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2311faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
23120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
23150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23300ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2331347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2332347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2336e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2340f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2355faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
23560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2358faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
23600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2370faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2377f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
23810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
23840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
23880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
23907b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
23917b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
23927b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
23937b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
23940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2398ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
23990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2400ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2401ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2413bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      depth=(ssize_t) ping_bit_depth;
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2415faa852bad40107edae19405e76a299057668d795glennrp      image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2416faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2417faa852bad40107edae19405e76a299057668d795glennrp          (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2418faa852bad40107edae19405e76a299057668d795glennrp          MagickTrue : MagickFalse;
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2420bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2423faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
24240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
24270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2429abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
2442faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2444bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
2448faa852bad40107edae19405e76a299057668d795glennrp                  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS)) &&
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2458faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB)
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2460faa852bad40107edae19405e76a299057668d795glennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2461bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2480bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2492faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2493bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (4*image->columns); x != 0; x--)
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2499faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (2*image->columns); x != 0; x--)
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2506faa852bad40107edae19405e76a299057668d795glennrp        if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_GRAY)
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
25090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2510faa852bad40107edae19405e76a299057668d795glennrp        if (ping_color_type == PNG_COLOR_TYPE_GRAY ||
2511faa852bad40107edae19405e76a299057668d795glennrp            ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2518faa852bad40107edae19405e76a299057668d795glennrp        else if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_RGB)
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
25210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2522faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_RGB ||
2523faa852bad40107edae19405e76a299057668d795glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2530faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
25340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2535faa852bad40107edae19405e76a299057668d795glennrp        if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
25380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2539faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
25420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2543faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
25460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2547faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
25500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25557a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
25567a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2557cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2558cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
25590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25607a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25617a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25627a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25677a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2587faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2596bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2599faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
26040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26085c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2611faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2615bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2618bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2627bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
263347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
265247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
266647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2669faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
268847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2691bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2694bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
270747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2708faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
27220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
27300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2731faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
273546f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
273947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
274347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2744faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
275347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
275647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2765bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
276680ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27717a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27727a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2773cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2774cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
277547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27767a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27777a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27787a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
27807a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
278347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2789b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2790b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27925c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27935c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2794aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27955c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27965c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27975c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27985c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27995c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2800aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
28015c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
280247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2806bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
28103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2813f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
282047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2821faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2831c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2833c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2837c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2843c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
284447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
285847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2865c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2868c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
28740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
28750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 SetOpacityPixelComponent(q,OpaqueOpacity);
28800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
28850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2886c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
28870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2888c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28913c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2892b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2893b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2894b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
289547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2897bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
29040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
29070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
29260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
29300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29343c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
294773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
295547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2988faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
29900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2991faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2992faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2993faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2994faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
2995faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
2996faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
2997faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
2998faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
29990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3000faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30133c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
301947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3032f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
307147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
307547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
308247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
308547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
309047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
309347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
309873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
309947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
310247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
311347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
313147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
313347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
314247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
315247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
31640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3216bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3239bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3255bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
32720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
32810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
32830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
32860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
33140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
33170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3325e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3326e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
333347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
33370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3341bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
334647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
335347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3361bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3363bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
336947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
337247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
337747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3381f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
338247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3384f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
338547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
338847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
339247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
339647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
340047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
340447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
340847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
341247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
341847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
342147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
343773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
343847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
344147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
34440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
34510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
34550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
346273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
34630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
34800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
34840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
34870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
34960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
34990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
351947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
352647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
352947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
353847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
356347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
35830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
36138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
36140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36238182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
36248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
36258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
36268182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
36278182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
36288182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
36298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
363247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3641e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3642e610a071534e448c46460a5aa39ede33bf56b329glennrp              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
365347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36628182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
36638182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
36640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
367147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
36838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
37120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
374147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
37450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
37480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
37510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
37650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
37690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
377547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
37810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
37980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
38070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
381447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3816bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
38260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
383847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
383947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
38470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
38490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
38500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
38530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
38550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
38590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
38600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
38610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
38620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
38660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
38700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
394647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
394747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
394947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
395347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
395447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
395673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
39570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
396147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
396247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
39700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
398647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
39980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4022bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4047bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4053bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4070bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
407938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
408038ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
408138ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4082bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
410447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
410547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
41150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
41180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
412247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
412347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
412447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
412573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
41260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
41290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
413047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
413147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
414147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
414547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
414647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4149bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4150bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
415447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4197e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4198e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
42020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
42050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
42080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
421247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
421547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4216bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
421847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
42320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
42390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
42430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
424847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
42530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
42600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4266bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
42680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4269bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
42710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4275e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4277e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
42818182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
42820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
42850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
42890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
42920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
42968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
43000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
43030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
43060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
431347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
43150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
43180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
43260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4327e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4328e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4329f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
43300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4332bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4334bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
43360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
43390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
43520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
43568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
43570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
43600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
43690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4371e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
43720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4374e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
43880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
44170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
44200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
44270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
44280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
44310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4435e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4436f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
44370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4439e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4440f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
44500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
44570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
44800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
44830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
450647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
450947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
451047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
45160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
452435ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
45390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
454347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4549bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
455612560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45678182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
45740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
458147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
458247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
45868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
45878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
45898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
45918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
45938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
45958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
45978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
460247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
460647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4614e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4615e610a071534e448c46460a5aa39ede33bf56b329glennrp                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
462047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
462447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
463447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
463747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
46470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
465147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
46550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
46590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
466247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
466347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
466547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4666bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
466847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
467047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
468247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
46868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
46870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
46898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
46900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4691bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4692bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
46930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
46960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
46980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4701e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
470347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4706bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4707bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
47080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4709bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4710bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
47110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4712bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4713bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
47140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
47170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
47190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4722e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
472447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
47300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4734e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4735e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
473647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
47440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4745bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
47470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4756e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4757e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
47580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
476247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
476647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
477347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
47780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
47880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
47990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4803e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4804e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
482147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
483347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
485747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
485847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
488247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4885bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
488947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
489047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4893bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
491047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
492047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
492147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
49228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
49230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4926e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4927e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
49280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
49310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
494247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
494647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
495847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
49650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
4969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4970f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
497147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
49760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
498147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
499947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
500347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
501047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
501347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
50300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
50330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
50360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
504747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
505347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
505947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
506247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
506847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
507147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
507747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
508047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
508647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
508947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
509547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
509847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
510447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
510747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
511347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
511747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
512547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
514447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
515147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
515447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
516147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
516447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
516947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
51858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
51878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
519147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
520047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
520647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
521147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5214bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5216bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
522447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
522747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
523047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
523347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
523647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
523947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
524247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
525047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
525347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
525647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
526147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
527147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
527847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
528147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
528747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
529547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
52978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5310bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5312bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
532047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
532747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
533147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
533847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
534147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
534247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
534347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5355e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
537347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
538047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
53830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
53850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
539547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
54060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5410e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5411e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
541547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
542247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
542947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
54350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
54380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
54470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
54560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
546247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
546647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
547147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
547347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
548547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
549847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
553147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
553447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
553647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
553747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
553947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55424e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
554347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
554647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
554947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
555147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
555247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
555847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
556147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
556347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
556447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
556647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55694e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
557047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
557347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
557647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
557847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
557947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
558147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5591bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
561047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
561147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
561547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
561747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
564547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
565447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
566547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
567047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
567347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
567647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
567947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5688e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5689bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
569447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
570347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
570647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5710bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
571147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5712bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
571447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
571747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
572047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5722bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
572347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
572747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
573447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5740bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
574647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5747bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
57495c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
576047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
576547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5769bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5772bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5775bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
577847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5783bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
578547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
579547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
580147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
580447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5807bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5808bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
581647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
581947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
582247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5841e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5843bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
585147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5852bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5853bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5855bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
585747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5858bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
586047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5862bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
586347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5864bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
586647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
586947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
587747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
588247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5891bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5894bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5897bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
590047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
591047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
591647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
591947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5924bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
593347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5943bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
594647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5947bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
595547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
598947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6005bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6006bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
601247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
602447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60472b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
60482b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
60492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
60502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
60512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
60522b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
60532b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
60542b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
60550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
60568640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
60578640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6059d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
606147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6065bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6068d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6072d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
607447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
607647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
608047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
60910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
610247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
610647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
61190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
61220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
61270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
613847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
614247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
61470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
615247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
615847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
616647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
617147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
617747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
618047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
618347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
61910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
61940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
61970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
620247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
62080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
62100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6213e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6214e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
62150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
622347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
622647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6228e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
622947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6234e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6246bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
625147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
625447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
625747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
626047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
626947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
627247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
628947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
629947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
630247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6304e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6305e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
630647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6308f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6309f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
631047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6311f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6312e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6313e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6314f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6315f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
631647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
632047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
632347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
632625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
633147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
633447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
633747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
634225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6365bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6368bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
638147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
638747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
639547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
639947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
640747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
641047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
641547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
641847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
642147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
642747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
643247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
643747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
644047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
644547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
645047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
646047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
646447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
647447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
647947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
648747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
649247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
650047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
650747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
651447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
651518b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
651618b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
651718b17443128598500357da7bff2f01683cf32890cristy#endif
651847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
654947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6551514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6552514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
655725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
66640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
66650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
66670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6686f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
668847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6689bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
669647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
670347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
670647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
672747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
672847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
672947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
673147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
673747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
673847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
673947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
674047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
674147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
674247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
674347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=CloneStringInfo(profile);
674447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data=GetStringInfoDatum(png_profile),
674547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            length=(png_uint_32) GetStringInfoLength(png_profile);
674647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
674747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
674847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
674947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
675047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
675147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
675247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
675347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            png_profile=DestroyStringInfo(png_profile);
675447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
675647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
675947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6781cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6782cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6783e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6784e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
67855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
678639992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
678739992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
67905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
67915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
67925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
68005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
68015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
68025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
680739992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6808991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6809991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6810991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6816bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
68280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
68295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
68305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
68315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
68325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
68335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
68345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6835bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
68375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
68385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6840bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
684139992b4dd9b12ef752d55b8e402c069698851f72glennrp    number_colors,
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6846dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6847dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
6848dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
6849dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
6850dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
6851dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
6852dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6857f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
68610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
68625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
68635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
68645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
68655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
68665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
68675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
68695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
68705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
68715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
68725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
68735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
68755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
68765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
68775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
68785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6879dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
6880dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
6881dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
6882dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
688339992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
6884991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6885991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6886991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6887991d11dd9c33e65872778b81aff1347cd2878154glennrp
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
68900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68913241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
68923241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
68933241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
68943241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
68953241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
68963241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
68973241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
68982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
68992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
69002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
69012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
69022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
69032b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
69042b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
69052b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
69068640fb5e9b1094f35f8beab436f81661b8a99448glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
69077e2c405930c984e8ffb49b26efdfe1649bf394d6cristy  if (image->depth == 16 && mng_info->write_png_colortype != 16)
69088640fb5e9b1094f35f8beab436f81661b8a99448glennrp    if (LosslessReduceDepthOK(image) != MagickFalse)
69098640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
69108640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
69118640fb5e9b1094f35f8beab436f81661b8a99448glennrp
691283c2de583a59e41b57be8036d1cf7392c01d03d7glennrp#ifdef PNG_BUILD_PALETTE
691383c2de583a59e41b57be8036d1cf7392c01d03d7glennrp  if (((mng_info->write_png_colortype-1) == PNG_COLOR_TYPE_PALETTE) ||
69147ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp      (mng_info->write_png_colortype == 0))
691583c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    {
691683c2de583a59e41b57be8036d1cf7392c01d03d7glennrp      /*
69177ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       * Sometimes we get DirectClass images that have 256 colors or fewer.
69187ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       * This code will convert them to PseudoClass and build a colormap.
69197ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       *
69203241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * Also, sometimes we get PseudoClass images with an out-of-date
69213241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       * colormap.  This code will replace the colormap with a new one.
69227ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       */
69237ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69247ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp           "    Enter BUILD_PALETTE:");
69253c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69267ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp      if (logging != MagickFalse)
692783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp        {
69283c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69297ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                "      image->columns=%.20g",(double) image->columns);
69307ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69317ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                "      image->rows=%.20g",(double) image->rows);
69327ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69337ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                "      image_matte=%.20g",(double) image->matte);
69347ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69357ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                "      image->depth=%.20g",(double) image->depth);
69367ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
69373c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69387ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       image->colors=GetNumberColors(image,(FILE *) NULL,&image->exception);
69397ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       image_colors=image->colors;
69403c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69417ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       if (logging != MagickFalse && image->colormap != NULL)
69427ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
69437ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69447ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp             "        i    (red,green,blue,opacity)");
69453c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69467ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         for (i=0; i < (ssize_t) image->colors; i++)
69477ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
69487ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69497ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               "        %d    (%d,%d,%d,%d)",
69507ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                (int) i,
69517ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                (int) image->colormap[i].red,
69527ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                (int) image->colormap[i].green,
69537ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                (int) image->colormap[i].blue,
69547ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                (int) image->colormap[i].opacity);
69557ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
69567ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       }
695783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
69587ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69597ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp           "      image->colors=%d",(int) image->colors);
69607ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp       if (image->colors <= 260)
69627ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
69637ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               /* Sometimes SetImageType(image,PaletteMatteType)
69647ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                * loses the transparency.  We work around this
69657ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                * problem by usng a trial clone.  After creating
69667ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                * a colormap for it and copying the colormap to
69677ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                * image, we destroy the clone.
69687ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                */
69697ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69707ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               ExceptionInfo
69717ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                 *exception;
69727ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69736415f15992ee2bef5a691e83905671c1801ced7bglennrp               PixelPacket
69743241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                 colormap[300];
69757ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69767ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               register const PixelPacket
69777ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                 *q;
69787ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69797ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               register IndexPacket
69807ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                 *indexes;
69817ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69827ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               exception=(&image->exception);
69833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69847ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69853241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                    "      Regenerate the colormap");
69863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
69877ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               for (y=0; y < (ssize_t) image->rows; y++)
69887ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp               {
69897ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                 q=GetVirtualPixels(image,0,y,image->columns,1,
69907ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                     exception);
69917ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69927ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                 if (q == (PixelPacket *) NULL)
69937ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                   break;
69947ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
69957ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                 if (y == 0)
69967ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                   {
69977ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                    /* Initialize the colormap */
69986415f15992ee2bef5a691e83905671c1801ced7bglennrp                     colormap[0]=*q;
69993241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70003241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     if (image->matte == MagickFalse)
70013241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           colormap[0].opacity = OpaqueOpacity;
70023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70037ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                     image_colors=1;
70047ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                    }
70057ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70067ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                  for (x=0; x < (ssize_t) image->columns; x++)
70077ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                     {
70087ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                        for (i=0; i<image_colors; i++)
70097ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                          {
70103241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                            if (((image->matte == MagickFalse ||
70113241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                                colormap[i].opacity == q->opacity)) &&
70123241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                                (IsColorEqual(colormap+i, (PixelPacket *) q)))
70137ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                              break;
70147ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                          }
70157ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70167ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                        if (i < image_colors)
70177ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                          {
70187ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                            q++;
70197ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                            continue;
70207ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                          }
70217ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70223241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        if (image_colors++ == 300)
70237ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                          break;
70247ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70256415f15992ee2bef5a691e83905671c1801ced7bglennrp                        colormap[i]=*q;
70263241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70273241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        if (image->matte == MagickFalse)
70283241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           colormap[i].opacity = OpaqueOpacity;
70297ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70307ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                        q++;
70317ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                     }
70323241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70333241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     if (x < (ssize_t) image->columns)
70343241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        break;
70357ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                  }
70363c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70373c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70383241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                  if (image_colors >= 300)
70393241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      image has more than 300 colors");
70413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                  else
70433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70443241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      image has %d colors",(int)image_colors);
70457ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
70463241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                  if (image_colors <= 256)
70473241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                  {
70483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                    PixelPacket
70493241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      opaque[256],
70503241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      semitransparent[256],
70513241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      transparent[256];
70523c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
70533241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                    int
70543241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      n,
70553241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      number_opaque,
70563241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      number_semitransparent,
70573241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      number_transparent;
70583241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70593241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                    /*
70603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                      Initialize image colormap.
70613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                    */
70623241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70633241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70643241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      Sort the new colormap");
70653241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     number_opaque=0,
70673241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     number_semitransparent=0,
70683241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     number_transparent=0;
70693241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70703241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     /* Sort palette, transparent first */;
70713241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (i=0; i<image_colors; i++)
70723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     {
70733241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        if (colormap[i].opacity == OpaqueOpacity)
70743241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           opaque[number_opaque++] = colormap[i];
70753241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70763241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        else if (colormap[i].opacity == TransparentOpacity)
70773241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           transparent[number_transparent++] = colormap[i];
70783241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70793241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        else
70803241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           semitransparent[number_semitransparent++] =
70813241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                               colormap[i];
70823241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     }
70833241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70843241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70853241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      number_transparent     = %d",
70863241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           number_transparent);
70873241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70883241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70893241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      number_opaque          = %d",
70903241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           number_opaque);
70913241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70923241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70933241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      number_semitransparent = %d",
70943241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           number_semitransparent);
70953241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70963241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     n = 0;
70973241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
70983241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (i=0; i<number_transparent; i++)
70993241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        colormap[n++] = transparent[i];
71003241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71013241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (i=0; i<number_semitransparent; i++)
71023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        colormap[n++] = semitransparent[i];
71033241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71043241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (i=0; i<number_opaque; i++)
71053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        colormap[n++] = opaque[i];
71063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71073241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (i=0; i<number_opaque; i++)
71083241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     {
71093241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        if (IsColorEqual(colormap+i,
71103241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           &image->background_color))
71113241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        break;
71123241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     }
71133241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71143241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     if (n < 256 && i == number_opaque)
71153241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     {
71163241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        colormap[n]=image->background_color;
71173241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        n++;
71183241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        image_colors++;
71193241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     }
71203241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71213241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     if (n != image_colors)
71223241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71233241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        "   image_colors (%d) and n (%d)  don't match",
71243241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        (int) image_colors, n);
71253241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71263241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     image->colors = image_colors;
71273241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71283241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71297ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                        "      AcquireImageColormap");
71303241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71313241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     if (AcquireImageColormap(image,image_colors) ==
71323241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         MagickFalse)
71337ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                        ThrowWriterException(ResourceLimitError,
71347ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                           "MemoryAllocationFailed");
71353c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71363241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (i=0; i<image_colors; i++)
71373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                        image->colormap[i] = colormap[i];
71387ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
71393241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71403241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           "      Update the pixel indexes");
71413241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     for (y=0; y < (ssize_t) image->rows; y++)
71433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     {
71443241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       q=GetAuthenticPixels(image,0,y,image->columns,1,
71453241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           exception);
71467ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
71473241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       if (q == (PixelPacket *) NULL)
71483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         break;
71493c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71503241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       indexes=GetAuthenticIndexQueue(image);
71513c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71523241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       for (x=0; x < (ssize_t) image->columns; x++)
71533241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       {
71543241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         for (i=0; i<image_colors; i++)
71553241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         {
71563241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           if ((image->matte == MagickFalse ||
71573241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                               image->colormap[i].opacity == q->opacity) &&
71583241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                               (IsColorEqual(&image->colormap[i],
71593241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                               (PixelPacket *) q)))
71603241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           {
71613241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                             indexes[x]=(IndexPacket) i;
71623241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                             break;
71633241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           }
71643241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         }
71653241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         q++;
71663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       }
71673241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
71683241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
71697ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                          break;
71703241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     }
717183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
71723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                  if (image->matte != MagickFalse)
71733241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                    {
71743241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       if (((mng_info->write_png_colortype-1) ==
71753241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           PNG_COLOR_TYPE_PALETTE) ||
71763241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           (mng_info->write_png_colortype == 0))
71773241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                          (void) SetImageType(image,PaletteMatteType);
71783241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     }
71793241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                   else
71803241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     {
71813241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                       if (((mng_info->write_png_colortype-1) ==
71823241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           PNG_COLOR_TYPE_PALETTE) ||
71833241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           (mng_info->write_png_colortype == 0))
71843241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         {
71853241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                            (void) SetImageType(image,PaletteType);
71863241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                           (void) SyncImage(image);
71873241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                         }
71883241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp                     }
71897ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                  }
71903241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp         }
71913c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71923b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && image->colormap != NULL)
71933c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
71943c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71953c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp                "       i     (red,green,blue,opacity)");
71963c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
71973c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            for (i=0; i < (ssize_t) image->colors; i++)
71983c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            {
71993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72007ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp                  "       %d     (%d,%d,%d,%d)",
72013c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp                   (int) i,
72023c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp                   (int) image->colormap[i].red,
72033c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp                   (int) image->colormap[i].green,
72043c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp                   (int) image->colormap[i].blue,
72053c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp                   (int) image->colormap[i].opacity);
72063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            }
72073c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
72083c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72093c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72103c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp              "    Exit BUILD_PALETTE:");
721183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp    }
72123c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp#endif /* PNG_BUILD_PALETTE */
72133c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72143c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
72153c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
72163c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
72173c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
72183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_colors=image->colors;
72193c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
722083c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
72210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
72228eb57274a813fc3f2e2f96b166eb569f5e17aa26glennrp    image_colors <= 256;
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
72310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
72350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
72390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
72410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7262f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
72722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
72772b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72802b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
72822b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
72834e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
72844e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
72852b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
72880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
72910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
72950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
72980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
73010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7305e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7307e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7309e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73118640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73138640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73158640fb5e9b1094f35f8beab436f81661b8a99448glennrp
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
73175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
7318dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
7324dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7325dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7329dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7330dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
7331dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7333dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7336dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
7337dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution);
7338dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution);
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7340991d11dd9c33e65872778b81aff1347cd2878154glennrp
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7343dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
7344dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
7345dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7347991d11dd9c33e65872778b81aff1347cd2878154glennrp
7348991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7351a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7352a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7354a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
7355a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
7356a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7357a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
7358a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
7359a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
73600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7361a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
7362a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
73630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7364a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
7365a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
73660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7367a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
7368a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
73690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7370a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
7371a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
73720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7373a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
7374a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
73750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7376a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
7377a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
73780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
73790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
73813b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
73823b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73833b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
73843b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
73853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
73873b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
73880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
73960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
739779f9995ecaa0e0daae607e9e88f257706730084dcristy  if ((mng_info->write_png_colortype-1) == PNG_COLOR_TYPE_PALETTE)
739879f9995ecaa0e0daae607e9e88f257706730084dcristy    mng_info->write_png8=MagickTrue;
73990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      QuantizeInfo
74030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        quantize_info;
74040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /* TO DO: make this a function cause it's used twice, except
74060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
74070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
74095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_bit_depth=8;
74105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
74130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((image->storage_class == DirectClass) || (number_colors > 256))
74140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
74150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          GetQuantizeInfo(&quantize_info);
74160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          quantize_info.dither=IsPaletteImage(image,&image->exception) ==
74170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            MagickFalse ? MagickTrue : MagickFalse;
74180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          quantize_info.number_colors= (matte != MagickFalse ? 255UL :
74190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            256UL);
74200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) QuantizeImage(&quantize_info,image);
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
74220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "    Colors quantized to %.20g",(double) number_colors);
74260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
74270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (matte)
74290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        ping_have_tRNS=MagickFalse;
74300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
74320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
74330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
74340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
74350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
74370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
74390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (int) number_colors, (int) image_colors);
74400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
74420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
74430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
74440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
74450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
74460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
74470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
74490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
74510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %5ld (%5d,%5d,%5d)",
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
74562b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (matte)
74580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
74590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          number_colors++;
74600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
74610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
74620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
74630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
74642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74652b013e4b9b602533eff410e61c3683fb2a3ab913glennrp        ping_have_PLTE=MagickTrue;
74660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        image_depth=ping_bit_depth;
74670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        ping_num_trans=0;
74682b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
74690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (matte)
74700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
74712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp          ExceptionInfo
74720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            *exception;
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          int
74750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            trans_alpha[256];
74765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
74770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
74780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
74790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
74800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (i=0; i < (ssize_t) number_colors; i++)
74830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             trans_alpha[i]=255;
74840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          exception=(&image->exception);
74860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
74880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
74890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            register const PixelPacket
74900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              *p;
74910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            p=GetVirtualPixels(image,0,y,image->columns,1,exception);
74930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (p == (PixelPacket *) NULL)
74950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
74960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
74970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=0; x < (ssize_t) image->columns; x++)
74980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
74990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              if (p->opacity != OpaqueOpacity)
75005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                {
75010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  trans_alpha[(ssize_t) number_colors-1]=(png_byte) (255-
75020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    ScaleQuantumToChar(GetOpacityPixelComponent(p)));
75035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                }
75040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              p++;
75050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
75060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
75072b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
75080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (i=0; i < (ssize_t) number_colors; i++)
75090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (trans_alpha[i] != 255)
75100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_num_trans=(unsigned short) (i+1);
75110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
75130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
75140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_have_tRNS==MagickFalse)
75160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_num_trans=0;
75175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans != 0)
75190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
75200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (i=0; i<256; i++)
75210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 ping_trans_alpha[i]=(png_byte) trans_alpha[i];
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          ping_have_tRNS=MagickTrue;
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
75280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Identify which colormap entry is the background color.
75290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
75300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
75310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (IsPNGColorEqual(ping_background,image->colormap[i]))
75320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          break;
75330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_background.index=(png_byte) i;
75350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
75410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
75455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
75515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
75570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
7561b905e45f528487c0e1c2a28b86b89f8ed86433a0cristy          image_matte=MagickFalse;
75620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
75645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75723c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
75730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) ((matte == MagickTrue)?
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
75760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((image_info->type == UndefinedType ||
75900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             image_info->type == OptimizeType ||
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
75990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             image_info->type == OptimizeType ||
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
76050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
760926c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76108640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
761126c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
76125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
76130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
76140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
76150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
76160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
76170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
76180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
76265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
76270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (ping_bit_depth < (int)mng_info->write_png_depth)
76295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth = mng_info->write_png_depth;
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76338640fb5e9b1094f35f8beab436f81661b8a99448glennrp
76345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
763635ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
76375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
76380f111984738842d27d04aed2a3f823d82a943506glennrp
76390f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
76400f111984738842d27d04aed2a3f823d82a943506glennrp           {
76410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
76420f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
76430f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
76440f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
76450f111984738842d27d04aed2a3f823d82a943506glennrp           }
76460f111984738842d27d04aed2a3f823d82a943506glennrp
76473b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
76483b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76493b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp               "  SyncImage.2.");
76500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
765135ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
76525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7657e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "    Number of colors: %.20g",(double) image_colors);
76580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                "    Tentative PNG bit depth: %d",ping_bit_depth);
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
76620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
76655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               old_bit_depth=ping_bit_depth;
76665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               if (ping_bit_depth < (int)mng_info->write_png_depth)
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
76685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth = mng_info->write_png_depth;
76690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth > 8)
76715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth = 8;
76720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth != (int) old_bit_depth)
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7677e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                           "    Colors increased to %.20g",(double)
7678f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                           image_colors);
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
76855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
76862b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7690e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
76910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7693e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
76940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7696e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
76970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
77008640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
77018640fb5e9b1094f35f8beab436f81661b8a99448glennrp
77028640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7703e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
770639992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (matte && (mng_info->IsPalette))
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
77125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
77132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
7714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
77190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7720bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
77302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7734bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
77400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7741bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
77443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
77463c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77502b013e4b9b602533eff410e61c3683fb2a3ab913glennrp        if (x >= 0)
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
77530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
775457e0d433937989b88ac2692fc2d9127bb1bbeafeglennrp      if ((y == (ssize_t) image->rows) && (x < 0))
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
77575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
77605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type&=0x03;
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
77690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 8)
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
77720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 4)
77743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
77750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 2)
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
77780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 1)
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
77810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.red=(png_uint_16)
7783ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetRedPixelComponent(p)) & mask);
77840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.green=(png_uint_16)
7786ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetGreenPixelComponent(p)) & mask);
77870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.blue=(png_uint_16)
7789ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetBluePixelComponent(p)) & mask);
77900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.gray=(png_uint_16)
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
77930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
77945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.index=(png_byte)
779546f08209f719f4adeea742c45873c2714e80cdb9cristy            (ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))));
77960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7797991d11dd9c33e65872778b81aff1347cd2878154glennrp          ping_have_tRNS=MagickTrue;
77983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78002e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp      if (ping_have_tRNS != MagickFalse)
78013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
7806bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
78093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
78110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7815bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
78195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p) == 0)
78200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    {
78210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       break;  /* Can't use RGB + tRNS for multiple
78220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                                  transparent colors.  */
78230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    }
78240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
78260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    {
78270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       break;  /* Can't use RGB + tRNS for
78280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                                  semitransparency. */
78290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    }
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
78310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp              else
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
78345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p))
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
78363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
78392b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp              p++;
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
7843217484eb7236f4f3527af0feb39a6dc19a3302fecristy            if (x >= 0)
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78473c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7848217484eb7236f4f3527af0feb39a6dc19a3302fecristy          if (x >= 0)
78492e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp            ping_have_tRNS = MagickFalse;
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78512b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78522e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp      if (ping_have_tRNS != MagickFalse)
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
78550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
78595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
78605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
78615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78658640fb5e9b1094f35f8beab436f81661b8a99448glennrp
78663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
78670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78682e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
78700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
787139992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
787535ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
78760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
78789c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
78790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
78813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
78845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray*=0x0101;
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
78890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
789135ef824baa82511126ff0072ae30eee0da9c05a3cristy          image_colors=one << image_depth;
78920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
78945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
78950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
78995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
79035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
79040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
790535ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
79075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79102b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
79120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
79173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7922bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
79310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
79340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
79409c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
79410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
79439c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
79440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
79469c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79492b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
79505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
79513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
79520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
79540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
795717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
795817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
79645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
79650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79689c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
79690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79703b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
79719c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79729c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79843b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
798698156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
798798156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
79880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
798939992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
79910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7995befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
7996befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
7997befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
79985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
7999befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
80000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8001befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
80025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
80060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
80080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
80090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ExceptionInfo
80100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  *exception;
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                register const PixelPacket
80130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  *p;
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                int
80160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  trans[256];
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                register const IndexPacket
80190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  *packet_indexes;
80200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
80220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  Identify which colormap entry is transparent.
80230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                */
80240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8026bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
80270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  trans[i]=256;
80280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                exception=(&image->exception);
80300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                for (y=0; y < (ssize_t) image->rows; y++)
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
80330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  p=GetVirtualPixels(image,0,y,image->columns,1,exception);
80340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  if (p == (const PixelPacket *) NULL)
80360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    break;
80370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  packet_indexes=GetVirtualIndexQueue(image);
80390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  for (x=0; x < (ssize_t) image->columns; x++)
80410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
80420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    if (p->opacity != OpaqueOpacity)
80430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      {
80440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        IndexPacket
80450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          packet_index;
80460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        packet_index=packet_indexes[x];
80480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        if((size_t) packet_index >= number_colors)
80500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          (void) LogMagickEvent(CoderEvent, GetMagickModule(),
80510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          "packet_index=%d, number_colors=%d",
80520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          (int) packet_index, (int) number_colors);
80530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        assert((size_t) packet_index < number_colors);
80550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        if (trans[(ssize_t) packet_index] != 256)
80570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          {
8058acfcbf3ea29bbb00eec23735e5b1cb247513bb6cglennrp                            if (trans[(ssize_t) packet_index] !=
8059acfcbf3ea29bbb00eec23735e5b1cb247513bb6cglennrp                                (png_byte) (255-
80600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                               ScaleQuantumToChar(GetOpacityPixelComponent(p))))
80610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                              {
80620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                                ping_color_type=(png_byte)
80630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                                  PNG_COLOR_TYPE_RGB_ALPHA;
80640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                                break;
80650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                              }
80660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          }
80670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        trans[(ssize_t) packet_index]=(png_byte) (255-
80690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                          ScaleQuantumToChar(GetOpacityPixelComponent(p)));
8070acfcbf3ea29bbb00eec23735e5b1cb247513bb6cglennrp
8071acfcbf3ea29bbb00eec23735e5b1cb247513bb6cglennrp                        ping_have_tRNS=MagickTrue;
80720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      }
80732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
80740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    p++;
80750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
80760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
80780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
80790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    ping_num_trans=0;
80800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    ping_have_tRNS=MagickFalse;
80810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    ping_have_PLTE=MagickFalse;
80820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    mng_info->IsPalette=MagickFalse;
80830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (void) SyncImage(image);
80840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                    if (logging != MagickFalse)
80860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (void) LogMagickEvent(CoderEvent, GetMagickModule(),
80870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "    Cannot write image as indexed PNG, writing RGBA.");
80882b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
80890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    break;
80900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
80920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_have_tRNS != MagickFalse)
80949c1eb0729653219b9da9037e044501a6dce79d10glennrp                {
80959c1eb0729653219b9da9037e044501a6dce79d10glennrp                  for (i=0; i < (ssize_t) number_colors; i++)
80960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
80970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    if (trans[i] == 256)
80980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      trans[i]=255;
80990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    if (trans[i] != 255)
81010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      ping_num_trans=(unsigned short) (i+1);
81020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
81039c1eb0729653219b9da9037e044501a6dce79d10glennrp                }
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
81060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
81070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_have_tRNS == MagickFalse)
81090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_num_trans=0;
81100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans != 0)
81120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
81130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    for (i=0; i < (ssize_t) number_colors; i++)
81140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        ping_trans_alpha[i]=(png_byte) trans[i];
81150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
81160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
81190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
81240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
81275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
81285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
81295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
81305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
81375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
814335ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
814435ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
814535ef824baa82511126ff0072ae30eee0da9c05a3cristy
814622ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8149a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81543c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
81553b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8156991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
81595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
816117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
816217a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
816317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
816417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
816517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
816617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
816717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
816817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
816917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8170a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8171a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
817217a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
817317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
817417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
817517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
81763c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp        if (i == (ssize_t) number_colors)
81773c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp        {
81783c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          if (i < 255)
81793c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
81803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            number_colors++;
81813c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            image_colors++;
81823c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
81833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp        }
81843c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
81853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
81860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
81870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
81890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8190a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
819113d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8192a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
81930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
81943b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
81953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
81960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
81970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
81990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
82000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
82010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
82020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8203a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
820417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8205a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        else
82063c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
82073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
82083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82093b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
82103c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
82113c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
821217a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
821317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
82220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
82240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
82270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
82280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
82300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
82340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
82360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
82390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8245bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
82460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
82500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
82590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82672b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
82740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
82832b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
82898640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
82900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82918640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
82928640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
82940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82958640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
82968640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
82975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
82998640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
83000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83018640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
83028640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
83030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
83132b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
83153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
83212b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
83245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
83270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
83310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
83382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
83420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
83570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8358e610a071534e448c46460a5aa39ede33bf56b329glennrp      (void) png_set_sRGB(ping,ping_info,(
8359e610a071534e448c46460a5aa39ede33bf56b329glennrp        PNG_RenderingIntent_from_Magick_RenderingIntent(
8360e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent)));
83610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
83763b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83792b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
83903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
84013b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8406dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
84075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
84195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
84202b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
84215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
84225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
84240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
84275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
84315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
84335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
8434991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
84355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
84363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
84445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
84515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
84523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84543bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84588640fb5e9b1094f35f8beab436f81661b8a99448glennrp  if (image_matte && !image->matte)
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
84630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8464b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
8465b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8466b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8469991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->matte == MagickTrue)
8470e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
8471991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
8472991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (ping_color_type != 3 || ping_num_trans > 0)
8473991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
8474e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
8475e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
84815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
84825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
84835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
84845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
848539992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
848639992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
848739992b4dd9b12ef752d55b8e402c069698851f72glennrp      png_set_PLTE(ping,ping_info,palette,(int) number_colors);
84880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84893b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
849039992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
84918640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
84920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
84930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (ping_num_trans != 0)
84940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "     PLTE[%d] + tRNS[%d]   =(%d,%d,%d,%d)",
84960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,(int) i,
84970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
84980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
84990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
85000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
85010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
85020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "     PLTE[%d] =(%d,%d,%d)",
85040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
85050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
85060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
85070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
85080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
850939992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
851039992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
851139992b4dd9b12ef752d55b8e402c069698851f72glennrp
8512991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (ping_have_bKGD != MagickFalse)
8513991d11dd9c33e65872778b81aff1347cd2878154glennrp      png_set_bKGD(ping,ping_info,&ping_background);
8514991d11dd9c33e65872778b81aff1347cd2878154glennrp
8515dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  if (ping_have_pHYs != MagickFalse)
8516dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
8517dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp       png_set_pHYs(ping,ping_info,
8518dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp           ping_pHYs_x_resolution,
8519dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp           ping_pHYs_y_resolution,
8520dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp           ping_pHYs_unit_type);
8521dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8522dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8523dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
8524dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  if (image->page.x || image->page.y)
8525dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
8526dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
8527dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          (png_int_32) image->page.y, 0);
8528dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
8529dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp       if (logging != MagickFalse)
8530dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8531dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp             "    Setting up oFFs chunk with x=%d, y=%d, units=0",
8532dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp             (int) image->page.x, (int) image->page.y);
8533dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
8534dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
8535dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
8537991d11dd9c33e65872778b81aff1347cd2878154glennrp
853839992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
8539991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
85403b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
85410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
85420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
85440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
8545991d11dd9c33e65872778b81aff1347cd2878154glennrp
85460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
85470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
85480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
85490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
85500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
8551991d11dd9c33e65872778b81aff1347cd2878154glennrp
85520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
85530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
85540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
85550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
85560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
85570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
85580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85593b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
85600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
85610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 "     background   =(%d,%d,%d)",
85630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
85640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
85650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
85660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
85670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
85680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
8569991d11dd9c33e65872778b81aff1347cd2878154glennrp
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
8573991d11dd9c33e65872778b81aff1347cd2878154glennrp
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85799c1eb0729653219b9da9037e044501a6dce79d10glennrp      unsigned char
85809c1eb0729653219b9da9037e044501a6dce79d10glennrp        chunk[14];
85819c1eb0729653219b9da9037e044501a6dce79d10glennrp
85829c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
85839c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGType(chunk,mng_vpAg);
85849c1eb0729653219b9da9037e044501a6dce79d10glennrp      LogPNGChunk((int) logging,mng_vpAg,9L);
85859c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+4,(png_uint_32) image->page.width);
85869c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+8,(png_uint_32) image->page.height);
85879c1eb0729653219b9da9037e044501a6dce79d10glennrp      chunk[12]=0;   /* unit = pixels */
85889c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlob(image,13,chunk);
85899c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
85939c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
85959c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
8604b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
8605b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
86067202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8608b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
8610b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8612b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
8613b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
8614b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8616b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
8618b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8620b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
8621b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86233b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
86243b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
86253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8626b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8627b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
86280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8629b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8630e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
86340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8656f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8660ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8661ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
8662ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
866839992b4dd9b12ef752d55b8e402c069698851f72glennrp      (mng_info->IsPalette ||
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
86740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
8681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8683a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
86843241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp          if (logging != MagickFalse)
86853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86863b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
8687a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
86890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
86920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
8702bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
8715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
87180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
8720b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8721b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
87220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
87435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
874439992b4dd9b12ef752d55b8e402c069698851f72glennrp         (mng_info->IsPalette) && ImageIsGray(image))
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
87490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
87520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
87580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
87620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              if (logging != MagickFalse && y == 0)
8764b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8765b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                     "    Writing GRAY PNG pixels (2)");
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
87703b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              if (logging != MagickFalse && y == 0)
8771b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8772b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (2)");
87730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87773b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
87783b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
8779b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8780b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (2)");
87810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
8798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
88010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
88040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
88100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
88150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
8817b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
8818b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8819b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
88200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8822b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8823b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (3)");
8824b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
88250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
88290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
88330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88343b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
8835b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8836b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "    Writing row of pixels (3)");
88370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
88475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
88493b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              if (logging != MagickFalse)
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
88520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88583b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
88610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
88630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
88660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
88700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
8872b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
88733b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
8874b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8875b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "  Writing GRAY_ALPHA PNG pixels (4)");
88760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8877b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8878b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
8879b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
88800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
88840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88853b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              if (logging != MagickFalse && y <= 2)
88868640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
88878640fb5e9b1094f35f8beab436f81661b8a99448glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88888640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    "  Writing row of pixels (4)");
88890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88908640fb5e9b1094f35f8beab436f81661b8a99448glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88918640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    "  png_pixels[0]=%d,png_pixels[1]=%d",
88928640fb5e9b1094f35f8beab436f81661b8a99448glennrp                    (int)png_pixels[0],(int)png_pixels[1]);
88938640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8905b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
8906b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8911b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
89120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8914e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
89150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8917e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
89180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
89270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
89360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
89600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
89650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
89820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
89840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
89885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
89895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
90105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
90135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
90280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  s[0]=(char) ping_bit_depth;
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9047f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
90530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
91070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9112bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9113bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9114bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
9156bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
9157bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
9162bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9164bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
91663241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
91670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
9168d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
91690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
91700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
91710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
91723241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%      transparent color first, if PNG_BUILD_PALETTE is defined.
91730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
9174d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
9175d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
9176d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
9177d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
9178d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
9179d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
9180d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
91810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
921873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
92190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
92220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
9228a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92399c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
92409c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92419c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92469c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
92479c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92489c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92509c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
92519c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
92520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92539c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
92549c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
92550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92569c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92619c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
92629c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
92639c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
92640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92659c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
92669c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
92670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92689c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
92699c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
92700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92719c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
92789c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
92790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
92819c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
92820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
92849c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
92850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
92879c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
92880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
92909c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
92910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9292bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9293bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9294bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9295bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
9296bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9297bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
92999c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9300bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
93040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
93099c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
93100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
93129c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
93130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
93159c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
93160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
93189c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
93190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
93219c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
93220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9323bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
9324bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
9325bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
9326bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
9327bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
9328bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
93309c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
933139992b4dd9b12ef752d55b8e402c069698851f72glennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype);
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
93390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
93420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
94050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
94100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
94120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
94190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
94210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
94290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
94320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
94350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
9491f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
94930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9496e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
9497e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
95104e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
95114e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
95193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
95203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
95233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9525f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
95260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9528f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
95290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
95320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
95350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
95380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
95410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
95440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
95470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
95500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
95653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
95793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
9580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
95813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
9582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    LogPNGChunk((int) logging,mng_bKGD,(size_t) (num_bytes-4L));
95833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
95843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
95863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
95883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
95893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
95913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
95923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
95993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
96023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
96033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
96040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
9606e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
9607e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
9608e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
96090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
9611e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
9612e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
9613e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
96140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
96163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
96243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
96263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
962835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
96423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
964635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
964735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
964935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
965035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
965235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
965335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
965535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
965635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
96593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
96683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
96713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
967235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
96733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
96740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
967535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
96763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
96770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
96800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
96823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
96833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
96843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
968535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
96870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
968835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
96893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
96900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
96930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
96953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
969635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
969735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
96993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
97023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
97063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
97083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
97093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
97103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
97113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
9713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
9714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
97163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
97173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
97273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
97283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
97293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
97333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9736bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9739bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9745e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
9746f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
9751bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
97550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
97573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
9759bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
9760bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                LogPNGChunk((int) logging,mng_IDAT,(size_t) len);
97613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
97650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
97673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
97693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9770e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
9771e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
97733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9781e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
9782bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
97883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
97923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
97953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
97983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
98013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
98123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
98133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
98143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
98173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9820e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
9821e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
98250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
98290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
98330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
98350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9839e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
9840e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9843e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
9847bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
98720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
98953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
98993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
99263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
99303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
99323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
99343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
993573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
99363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
99403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
99413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
99623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
99633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
99813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
99823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
99833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
99843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
99883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9990bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10000bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
100023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10003bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
100063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10007d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
100083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
100123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
100173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
100183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
100193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
100203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
100213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
100223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
100233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
100243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
100253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
100283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1003073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
100313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
100383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
100393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
100403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
100443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
100503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
100513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
100613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
100663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
100673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
100710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10073e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
100740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
100793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10082e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
100830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10085e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
100860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
100883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
100900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
100923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
100940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
100963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
100973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
100980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
101003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
101020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
101043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10105e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
101060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
101083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
101100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
101123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
101133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
101143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
101173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
101183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
101193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
101233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
101253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
101273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
101283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
101303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
101313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
101343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
101373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
101393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
101423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
101433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
101443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
101453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
101473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
101483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
101493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
101513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
101533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
101573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
101593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
101613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
101723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
101730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
101763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
101770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
101793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
101800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
101830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
101863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
101873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
101883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
101890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
101913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
101920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
101940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
101963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
101973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
101980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
102003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
102013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
102023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
102033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
102043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
102053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
102060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
102093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
102153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
102163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
102193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
102213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
102223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
102243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
102260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
102283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
102290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
102313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
102323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
102330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
102353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
102373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
102380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
102403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
102413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
102423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
102433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
102443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
102463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
102473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
102493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
102513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
102533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
102543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
102563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
102583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
102593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
102603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
102613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
102623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
102633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
102643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
102663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
102693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
102703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
102723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
102753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
102813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
102843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
102853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
102863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
102873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
102883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
102893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
102900261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
10291d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
10292d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
10293d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
10294d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
10295d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
10296d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
10297d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
102993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
103003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
103034e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
103053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
103060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
103083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
103090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
103113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
103120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
103143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
103163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
103173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
103183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
103190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
103213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
103223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
103233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
103253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
103263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
103283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
103293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
103303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
103313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
103323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
103333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
103344e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
103354e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
103363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
103373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
103383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
103393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
103403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
103413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
103423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
103433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
103443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
103453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
103460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
103483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
103493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
103500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
103523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
103533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
103543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
103550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
103573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
103583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
103593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
103600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
103623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
103633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
103643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
103653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
103663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
103670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
103693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
103703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
103710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
103733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
103743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
103753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
103760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
103783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
103793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
103803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
103813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
103823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
103833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
103843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
103853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
103863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
103873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
103883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
103903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
103913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
103923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
103933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
10394bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
10395bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         LogPNGChunk((int) logging,mng_nEED,(size_t) length);
103963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
103973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
103983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
103993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
104003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
104013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
104023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
104033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
104043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
104053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
104063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
104073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
104083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
104093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
104103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
104113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
104123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
104133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
104140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
104163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
104170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
104193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
104200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
104223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
104233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10424e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
10425e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
104260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
104283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10429e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
104300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
104323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10433e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
104343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
104353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
104363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
104373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
104383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
104393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
104403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
104413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
104423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
104433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
104443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
104453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
104463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
104473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
104483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
104493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
104500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
10452e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10453e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10454e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
104550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
10457e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
10458e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
10459e610a071534e448c46460a5aa39ede33bf56b329glennrp             (PerceptualIntent));
104600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
104623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
104633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
104643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
104650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
104663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
104673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
104683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
104693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
104703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
104713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
104723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
104733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
104743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
104753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
1047635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
104773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
104783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
104793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
104803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
104813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
104823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
104833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
104843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
104853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
104863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
104873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
104883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
104893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
104903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
104913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
104923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1049335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1049435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
104953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1049635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1049735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
104983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1049935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1050035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
105013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1050235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1050335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
105043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
105093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
105103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
105123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
105133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
105153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
105163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
105170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1052035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
105220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1052335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
105243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
105250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
105280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
105313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1053335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
105343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
105350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1053635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
105380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
105410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
105433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1054435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1054535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
105463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
105473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
105483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
105493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
105503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
105513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
105523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
105533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
105543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
105553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
105563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
105573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
105583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
105593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
105603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
105613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
105623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
105643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
105673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
105703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
105873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
10588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
105963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
105980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
106050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
106083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
10643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
106500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
106570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
107213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
107243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
107253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
107373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
107383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
107434e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
107573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
107633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
107833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
107840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
107870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
107890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
108080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
108110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10814d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1081539992b4dd9b12ef752d55b8e402c069698851f72glennrp
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
108210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1082539992b4dd9b12ef752d55b8e402c069698851f72glennrp
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10830d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10832