png.c revision 991d11dd9c33e65872778b81aff1347cd2878154
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%                                                                             %
2116af1cbdffcc02e7239d432e5fb51734fcf9f9ffcristy%  Copyright 1999-2010 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 */
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_BUILD_PALETTE   /* This works as of 5.4.3. */
116a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#define PNG_SORT_PALETTE    /* This works as of 5.4.0 but not in 6.5. */
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *png_semaphore = (SemaphoreInfo *) NULL;
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
175bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrptypedef struct _UShortPixelPacket
24605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp{
24705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  unsigned short
24805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    red,
24905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    green,
25005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    blue,
25105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    opacity,
25205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    index;
25305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp} UShortPixelPacket;
25405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2668182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
354bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40035ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
479e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
480e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
481e610a071534e448c46460a5aa39ede33bf56b329glennrp{
482e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
483e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
484e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
485e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
486e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
487e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
488e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
489e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
490e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
491e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
492e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
493e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
494e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
495e610a071534e448c46460a5aa39ede33bf56b329glennrp}
496e610a071534e448c46460a5aa39ede33bf56b329glennrp
497e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
498e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
499e610a071534e448c46460a5aa39ede33bf56b329glennrp{
500e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (png_intent)
501e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
502e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
503e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
504e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
505e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
506e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
507e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
508e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
509e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
510e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
511e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
512e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
513e610a071534e448c46460a5aa39ede33bf56b329glennrp}
514e610a071534e448c46460a5aa39ede33bf56b329glennrp
515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
528d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
529dbb105fc25903e800273f7e980c0553060858a68glennrp
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
535dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
541dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
542dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
543dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
545dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
552dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
553dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
558dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
559dbb105fc25903e800273f7e980c0553060858a68glennrp
560dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
562dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
563dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
564dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
565dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
567bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
571dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
572dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
573dbb105fc25903e800273f7e980c0553060858a68glennrp    {
574dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
575dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
576dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
577dbb105fc25903e800273f7e980c0553060858a68glennrp    }
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
579dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
580dbb105fc25903e800273f7e980c0553060858a68glennrp}
581dbb105fc25903e800273f7e980c0553060858a68glennrp
582dbb105fc25903e800273f7e980c0553060858a68glennrp/*
583dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
585dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
586dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
587dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s M o n o c h r o m e                                         %
588dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
589dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
590dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
591dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
593dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
594dbb105fc25903e800273f7e980c0553060858a68glennrp%   and is more accurate.                                                     %
595dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
596dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597dbb105fc25903e800273f7e980c0553060858a68glennrp*/
598dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsMonochrome(Image *image)
599dbb105fc25903e800273f7e980c0553060858a68glennrp{
600dbb105fc25903e800273f7e980c0553060858a68glennrp  register const PixelPacket
601dbb105fc25903e800273f7e980c0553060858a68glennrp    *p;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
603dbb105fc25903e800273f7e980c0553060858a68glennrp  register ssize_t
604dbb105fc25903e800273f7e980c0553060858a68glennrp    i,
605dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
606dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
607a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
608dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image != (Image *) NULL);
609dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image->signature == MagickSignature);
610a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if (image->debug != MagickFalse)
611dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
612dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
613a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp    {
614dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
615dbb105fc25903e800273f7e980c0553060858a68glennrp      {
616dbb105fc25903e800273f7e980c0553060858a68glennrp        if ((IsGray(image->colormap+i) == MagickFalse) ||
617dbb105fc25903e800273f7e980c0553060858a68glennrp            ((image->colormap[i].red != 0) &&
618dbb105fc25903e800273f7e980c0553060858a68glennrp             (image->colormap[i].red != (Quantum) QuantumRange)))
619dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
620dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
623dbb105fc25903e800273f7e980c0553060858a68glennrp  for (y=0; y < (ssize_t) image->rows; y++)
624dbb105fc25903e800273f7e980c0553060858a68glennrp  {
625dbb105fc25903e800273f7e980c0553060858a68glennrp    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
626dbb105fc25903e800273f7e980c0553060858a68glennrp    if (p == (const PixelPacket *) NULL)
627dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
628dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
642d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
754d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
755bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
777a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
785a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
802e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
803e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
805d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
811d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
925e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
926e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
954bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1027bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1041bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
1050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1087bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1089bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1097bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1135bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1136bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1137bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1138bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1155bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
11588182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11678182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11698182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
1183faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1185faa852bad40107edae19405e76a299057668d795glennrp#else
1186faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1187faa852bad40107edae19405e76a299057668d795glennrp#endif
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1200cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1242bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
1273f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
1294bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
1354bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1409faa852bad40107edae19405e76a299057668d795glennrp    pass,
1410faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1411faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1412faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1413faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1414faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1415faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
142005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  UShortPixelPacket
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1423faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1424faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1425faa852bad40107edae19405e76a299057668d795glennrp
1426faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1427faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1428faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1429faa852bad40107edae19405e76a299057668d795glennrp
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1440faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1441faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1442faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1443faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1444faa852bad40107edae19405e76a299057668d795glennrp
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
14585c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1460bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1470bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1489f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
149225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
149861b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
149961b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
150061b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
150161b4c957269727a0a2526edc2331881da8346100glennrp    {
150261b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
150361b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
150461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
150561b4c957269727a0a2526edc2331881da8346100glennrp    }
150661b4c957269727a0a2526edc2331881da8346100glennrp#  endif
150761b4c957269727a0a2526edc2331881da8346100glennrp#endif
150861b4c957269727a0a2526edc2331881da8346100glennrp
150961b4c957269727a0a2526edc2331881da8346100glennrp
1510ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
1539faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1546f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
15527b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
15537b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
15547b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
15557b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1561faa852bad40107edae19405e76a299057668d795glennrp
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1595991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1596991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1597991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1611991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1615faa852bad40107edae19405e76a299057668d795glennrp
1616faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1617faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1618faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1619faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1620faa852bad40107edae19405e76a299057668d795glennrp
1621faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1622faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1623faa852bad40107edae19405e76a299057668d795glennrp
1624faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1625faa852bad40107edae19405e76a299057668d795glennrp
1626faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1628faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1629faa852bad40107edae19405e76a299057668d795glennrp        {
1630faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1631faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1632faa852bad40107edae19405e76a299057668d795glennrp        }
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1634faa852bad40107edae19405e76a299057668d795glennrp
1635faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1637faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1641e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1642e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1645faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1648faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1651faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1654faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1655faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1690e610a071534e448c46460a5aa39ede33bf56b329glennrp      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1691e610a071534e448c46460a5aa39ede33bf56b329glennrp        mng_info->global_srgb_intent);
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1694e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1695e610a071534e448c46460a5aa39ede33bf56b329glennrp          intent);
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1698e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1706faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1707faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1708faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1717faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1718faa852bad40107edae19405e76a299057668d795glennrp    {
1719faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1720faa852bad40107edae19405e76a299057668d795glennrp        {
1721faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1722faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1723faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1724faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1725faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1726faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1727faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1728faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1729faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1730faa852bad40107edae19405e76a299057668d795glennrp        }
1731faa852bad40107edae19405e76a299057668d795glennrp    }
1732faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1747e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1749e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1750e610a071534e448c46460a5aa39ede33bf56b329glennrp         PNG_RenderingIntent_from_Magick_RenderingIntent(
1751e610a071534e448c46460a5aa39ede33bf56b329glennrp         image->rendering_intent));
1752faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1753faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1754faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1755faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1758faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1765e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1766e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1770faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1771faa852bad40107edae19405e76a299057668d795glennrp    {
1772faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1773faa852bad40107edae19405e76a299057668d795glennrp        {
1774faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1775faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1776faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1777faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1778faa852bad40107edae19405e76a299057668d795glennrp        }
1779faa852bad40107edae19405e76a299057668d795glennrp    }
1780faa852bad40107edae19405e76a299057668d795glennrp
1781faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
17940881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
17950881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
17960881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1805e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1806e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1809faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
1819faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
1825faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1842faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1851faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
1852faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
1871faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
1872faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
1874faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
18822cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1884faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
1885faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
1886faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
18882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
18912cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
18922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
18932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
18942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
18962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
18972cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
18982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
18992cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
19002cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
19012cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
19022cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
19032cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
19042cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
19052cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
19062cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
19072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
19082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
19092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
19102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
19112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
19122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
19132cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
19142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19152cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
19162cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
19182cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
19192cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
19202cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
1922faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
1924faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
1926faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
1927f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
19282cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
19292cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
19302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1931e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
1932e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
1933e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
1934e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
1942faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
195035ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
195135ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
195235ef824baa82511126ff0072ae30eee0da9c05a3cristy
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1957f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1959faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
1960faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
1961faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
1962faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
1963faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
1964faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
1970faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
197505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.red= (unsigned short)(ping_trans_color->red);
197605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.green= (unsigned short) (ping_trans_color->green);
197705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.blue= (unsigned short) (ping_trans_color->blue);
197805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.opacity= (unsigned short) (ping_trans_color->gray);
197905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
1980faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19820f111984738842d27d04aed2a3f823d82a943506glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
19830f111984738842d27d04aed2a3f823d82a943506glennrp              if (ping_bit_depth < MAGICKCORE_QUANTUM_DEPTH)
19840f111984738842d27d04aed2a3f823d82a943506glennrp#endif
198505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              transparent_color.opacity=(unsigned short) (
19860f111984738842d27d04aed2a3f823d82a943506glennrp                  ping_trans_color->gray *
198705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                  (65535L/((1UL << ping_bit_depth)-1)));
19880f111984738842d27d04aed2a3f823d82a943506glennrp
198905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
199005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              else
199105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity=(unsigned short) (
199205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                    (ping_trans_color->gray * 65535L)/
199305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                   ((1UL << ping_bit_depth)-1));
19940f111984738842d27d04aed2a3f823d82a943506glennrp#endif
19950f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
19960f111984738842d27d04aed2a3f823d82a943506glennrp              {
19970f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19980f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
19990f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20000f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
20010f111984738842d27d04aed2a3f823d82a943506glennrp              }
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2011faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2016faa852bad40107edae19405e76a299057668d795glennrp
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2018faa852bad40107edae19405e76a299057668d795glennrp
2019faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2020faa852bad40107edae19405e76a299057668d795glennrp
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2027bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2030faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2031faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2040faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2041faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2042faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2043faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2044faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2046befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2047befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2048befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2050befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2051befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2059faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2068bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2082faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2091bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2100bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2103faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
2106bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
21190ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2120347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2121347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2125e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2129f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2141faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2143faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2153faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2160f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
21707b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
21717b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
21727b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
21737b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2176ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
2177ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2178ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2189bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      depth=(ssize_t) ping_bit_depth;
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2191faa852bad40107edae19405e76a299057668d795glennrp      image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2192faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2193faa852bad40107edae19405e76a299057668d795glennrp          (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2194faa852bad40107edae19405e76a299057668d795glennrp          MagickTrue : MagickFalse;
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2199faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2203abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
2215faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2217bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
2221faa852bad40107edae19405e76a299057668d795glennrp                  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS)) &&
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2231faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2233faa852bad40107edae19405e76a299057668d795glennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2253bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2264faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (4*image->columns); x != 0; x--)
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2270faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2271bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (2*image->columns); x != 0; x--)
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2277faa852bad40107edae19405e76a299057668d795glennrp        if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_GRAY)
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
2280faa852bad40107edae19405e76a299057668d795glennrp        if (ping_color_type == PNG_COLOR_TYPE_GRAY ||
2281faa852bad40107edae19405e76a299057668d795glennrp            ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2287faa852bad40107edae19405e76a299057668d795glennrp        else if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_RGB)
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
2290faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_RGB ||
2291faa852bad40107edae19405e76a299057668d795glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2297faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
2301faa852bad40107edae19405e76a299057668d795glennrp        if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
2304faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
2307faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
2310faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23177a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
23187a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2319cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2320cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
23217a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
23227a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
23237a287bfadeadea12e47c2376ca78a5d101687142cristy          }
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
23277a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2346faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2355faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
23625c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2365faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2372bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2387bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2396bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2403bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2414faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2415bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2427bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2436bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2447faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2456bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2467faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
247146f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
2478faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2496bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
249780ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25007a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
25017a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2502cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2503cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
25047a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25057a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25067a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25087a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2516b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2517b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
25185c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
25195c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2520aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
25215c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
25225c6f789db7a30bad01ace12b09ad9cd471339e94cristy
25235c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
25245c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
25255c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2526aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
25275c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2538f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2545faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2555c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2556e805a647adebb9faefcbd7f9a73ca8e91870614acristy#if 1  /* balfour fix */
2557c11cf6a442f3046940608a5743a68cc891deb13eglennrp/* From imagemagick discourse server, 5 Feb 2010 */
2558c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2559c11cf6a442f3046940608a5743a68cc891deb13eglennrp    if (storage_class == PseudoClass)
2560c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2561faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2562c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2563faa852bad40107edae19405e76a299057668d795glennrp         for (x=0; x < ping_num_trans; x++)
2564c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
2565e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            image->colormap[x].opacity =
2566e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp              ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
2567c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2568c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2569faa852bad40107edae19405e76a299057668d795glennrp      else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2570c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
25715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         for (x=0; x < (int) image->colors; x++)
2572c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
257305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp            if (ScaleQuantumToShort(image->colormap[x].red) ==
257405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity)
2575c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
2576c11cf6a442f3046940608a5743a68cc891deb13eglennrp               image->colormap[x].opacity = (Quantum) TransparentOpacity;
2577c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
2578c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2579c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2580d027259799c88ed5e4f12d21a5366031bfef0904cristy      (void) SyncImage(image);
2581c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2582c11cf6a442f3046940608a5743a68cc891deb13eglennrp   else
2583c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2584c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2585bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
2586c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2587c11cf6a442f3046940608a5743a68cc891deb13eglennrp        image->storage_class=storage_class;
2588c11cf6a442f3046940608a5743a68cc891deb13eglennrp        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2589c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (q == (PixelPacket *) NULL)
2590c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
25915c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2592c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2593bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
2594c11cf6a442f3046940608a5743a68cc891deb13eglennrp          {
259505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp            if (ScaleQuantumToShort(q->red) == transparent_color.red &&
259605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->green) == transparent_color.green &&
259705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->blue) == transparent_color.blue)
2598c11cf6a442f3046940608a5743a68cc891deb13eglennrp               q->opacity=(Quantum) TransparentOpacity;
2599c11cf6a442f3046940608a5743a68cc891deb13eglennrp            else
2600c11cf6a442f3046940608a5743a68cc891deb13eglennrp              SetOpacityPixelComponent(q,OpaqueOpacity);
2601c11cf6a442f3046940608a5743a68cc891deb13eglennrp            q++;
2602c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
2603c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (SyncAuthenticPixels(image,exception) == MagickFalse)
2604c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
2605c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2606c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2607c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2608c11cf6a442f3046940608a5743a68cc891deb13eglennrp#else /* not balfour */
2609c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2610c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->storage_class=storage_class;
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26175c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (storage_class == PseudoClass)
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexPacket
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexpacket;
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2624faa852bad40107edae19405e76a299057668d795glennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2625bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26275c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2628faa852bad40107edae19405e76a299057668d795glennrp                if (indexpacket < ping_num_trans)
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=ScaleCharToQuantum((unsigned char)
2630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    (255-ping_trans_alpha[(ssize_t) indexpacket]));
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2632ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2635faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26385c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                q->red=image->colormap[(ssize_t) indexpacket].red;
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=q->red;
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=q->red;
264205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                if (ScaleQuantomToShort(q->red) == transparent_color.opacity)
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) TransparentOpacity;
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2645ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
2650bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
265205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp            if (ScaleQuantumToShort(q->red) == transparent_color.red &&
265305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->green) == transparent_color.green &&
265405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->blue) == transparent_color.blue)
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               q->opacity=(Quantum) TransparentOpacity;
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2657ce70c17bb6433add2eb069515a4f3105989e0662cristy              SetOpacityPixelComponent(q,OpaqueOpacity);
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2663c11cf6a442f3046940608a5743a68cc891deb13eglennrp#endif /* not balfour */
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2666b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2667b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2668b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
271573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
2748faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
2750faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2751faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2752faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2753faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
2754faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
2755faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
2756faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
2757faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
2758faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2788f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
28103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
28203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
284773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
28663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
28673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2950bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2973bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2989bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3053e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3054e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3065bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3082bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3084bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3099f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3101f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
314473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
316473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk to color_image->blob
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy IDAT header and chunk data to alpha_image->blob
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3241bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk data to alpha_image->blob
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
33028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
33128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
33138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
33148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
33158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
33168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
33178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
33188182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3328e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3329e610a071534e448c46460a5aa39ede33bf56b329glennrp              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
33498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33658182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
33668182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
3444bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3483bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3486bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the JNG image.
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.width=jng_width;
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.height=jng_height;
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.x=mng_info->x_off[mng_info->object_id];
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify JNG signature.
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
361373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3696bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3702bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
372838ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
372938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
373038ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
3731bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    following optimizations:
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  16-bit depth is reduced to 8 if all pixels contain samples whose
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       high byte and low byte are identical.
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Opaque matte channel is removed.
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  If matte channel is present but only one transparent color is
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       present, RGB+tRNS is written instead of RGBA
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       this can be done without loss.
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Palette is sorted to remove unused entries and to put a
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       transparent color first, if PNG_SORT_PALETTE is also defined.
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
378873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->optimize=image_info->type == OptimizeType;
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Verify MNG signature.
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize some nonzero members of the MngInfo structure.
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
3818bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3864e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
3865e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3919bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3924e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3926e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
39298182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
39408182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
3966e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
3967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
3968f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
3970bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
3972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
39918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4002e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4004e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4048bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) | (p[5] << 16) |
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
4050bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) | (p[9] << 16) |
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[10] << 8) | p[11]);
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4055e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4056f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4058e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4059f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global PLTE.
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
4122bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
412835ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4150bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
415712560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41688182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global cHRM
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41858182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
41868182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
41878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
41898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
41918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
41938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
41958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
41978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4212e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4213e610a071534e448c46460a5aa39ede33bf56b329glennrp                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Note the delay and frame clipping boundaries.
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
4255bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
4258bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
42718182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
42728182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
42738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
42748182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
4275bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4276bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4282e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4286bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4287bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
4288bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4289bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
4290bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4291bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4297e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4306e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Frame_clipping: L=%.20g R=%.20g T=%.20g B=%.20g",
4307e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4308e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
4316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
4318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4326e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4327e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4366e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4367e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4368e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read DISC or SEEK.
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4427bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4430bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4442bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              read MOVE
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4474bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Record starting point.
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44808182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4483e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4484e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4518e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        "  ENDL: LOOP level %.20g has %.20g remaining iterations ",
4519e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4520f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
47028182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
47048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
4727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
4729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
47938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
47948182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
4807bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
4809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Make a background rectangle.
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4848e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
4849e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4895e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4896e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
4897e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
4946bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
50034e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                   magnified_width += (png_uint_32) ((image->columns-2)*(mng_info->magn_mx));
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50074e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
50134e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                   magnified_width += (png_uint_32) ((image->columns-3)*(mng_info->magn_mx-1));
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
50214d368204aa5ac1b8716da0054988319952030438cristy                   magnified_height += (png_uint_32) ((image->rows-2)*(mng_info->magn_my));
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50254e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
50314e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                   magnified_height += (png_uint_32) ((image->rows-3)*(mng_info->magn_my-1));
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5046bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5091bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
5095bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5131e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5132bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
5147bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5150bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
5151bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5152bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5153bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5155bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5158bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
5162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5173bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
5179bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
51815c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5199bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5200bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5202bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5203bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5206bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5209bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5212bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5232bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5233bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5263e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
5273bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5274bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5277bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
5278bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5279bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5281bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5282bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5285bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5305bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5311bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5334bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
5355bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
5411bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
5412bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* Determine if bit depth can be reduced from 16 to 8.
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * Note that the method GetImageDepth doesn't check background
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * and doesn't handle PseudoClass specially.  Also it uses
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * multiplication and division by 257 instead of shifting, so
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * might be slower.
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->optimize && image->depth == 16)
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ok_to_reduce;
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const PixelPacket
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *p;
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5466bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ok_to_reduce=(((((size_t) image->background_color.red >> 8) &
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     0xff)
5468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.red & 0xff)) &&
5469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.green >> 8) & 0xff)
5470bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.green & 0xff)) &&
5471bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.blue >> 8) & 0xff)
5472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.blue & 0xff)));
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce && image->storage_class == PseudoClass)
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int indx;
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (indx=0; indx < (ssize_t) image->colors; indx++)
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5479bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    8) & 0xff)
5481bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5482bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5483bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5484bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5485bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].blue & 0xff)));
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == MagickFalse)
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((ok_to_reduce != MagickFalse) &&
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->storage_class != PseudoClass))
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5493bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              y;
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5496bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              x;
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5499bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (y=0; y < (ssize_t) image->rows; y++)
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=((
5507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->red >> 8) & 0xff) ==
5508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->red & 0xff)) &&
5509bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->green >> 8) & 0xff) ==
5510bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->green & 0xff)) &&
5511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->blue >> 8) & 0xff) ==
5512bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->blue & 0xff)) &&
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((!image->matte ||
5514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->opacity >> 8) & 0xff) ==
5515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->opacity & 0xff)))));
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == 0)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (x != 0)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce)
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->depth=8;
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Reducing PNG bit depth to 8 without loss of info");
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
5537bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5655e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
5656e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5667e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5672e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5733e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
5734e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
5736f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
5737f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
5738f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5739e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
5740e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
5741f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
5742f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
575025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
576325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5789bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
591118b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
591218b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
591318b17443128598500357da7bff2f01683cf32890cristy#endif
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
5945514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
5946514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
595125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6037bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
6058e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy     (void) printf("writing raw profile: type=%s, length=%.20g\n",
6059e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy       (char *) profile_type, (double) length);
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6079f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
6081bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (LocaleNCompare(name,string,11) == 0) {
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Found %s profile",name);
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=CloneStringInfo(profile);
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data=GetStringInfoDatum(png_profile),
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       length=(png_uint_32) GetStringInfoLength(png_profile);
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[4]=data[3];
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[3]=data[2];
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[2]=data[1];
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[1]=data[0];
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,length-5);  /* data length */
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,length-1,data+1);
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=DestroyStringInfo(png_profile);
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6146dbb105fc25903e800273f7e980c0553060858a68glennrp#if defined(PNG_SORT_PALETTE)
6147dbb105fc25903e800273f7e980c0553060858a68glennrp/*
6148dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6149dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
6150dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
6151dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
6152747aad10b49e665a439b920009ed92cc08e58741glennrp%   O p t i m i z e P N G C o l o r m a p                                     %
6153dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
6154dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
6155dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
6156dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6157dbb105fc25903e800273f7e980c0553060858a68glennrp%
6158991d11dd9c33e65872778b81aff1347cd2878154glennrp%  OptimizePNGColormap compresses an image colormap removing any
6159991d11dd9c33e65872778b81aff1347cd2878154glennrp%  duplicate and unused color entries and putting the transparent colors
6160dbb105fc25903e800273f7e980c0553060858a68glennrp%  first.  Returns MagickTrue on success, MagickFalse on error.
6161dbb105fc25903e800273f7e980c0553060858a68glennrp%
6162747aad10b49e665a439b920009ed92cc08e58741glennrp%  The format of the OptimizePNGColormap method is:
6163dbb105fc25903e800273f7e980c0553060858a68glennrp%
6164747aad10b49e665a439b920009ed92cc08e58741glennrp%      unsigned int OptimizePNGColormap(Image *image)
6165dbb105fc25903e800273f7e980c0553060858a68glennrp%
6166dbb105fc25903e800273f7e980c0553060858a68glennrp%  A description of each parameter follows:
6167dbb105fc25903e800273f7e980c0553060858a68glennrp%
6168dbb105fc25903e800273f7e980c0553060858a68glennrp%    o image: the address of a structure of type Image.
6169991d11dd9c33e65872778b81aff1347cd2878154glennrp%
6170991d11dd9c33e65872778b81aff1347cd2878154glennrp%    o ping_plte_map: a mapping of indexes in image->colormap to those in
6171991d11dd9c33e65872778b81aff1347cd2878154glennrp%           the revised colormap
6172991d11dd9c33e65872778b81aff1347cd2878154glennrp%
6173991d11dd9c33e65872778b81aff1347cd2878154glennrp%    o opacity: opacity of pixels corresponding to the revised colormap
6174dbb105fc25903e800273f7e980c0553060858a68glennrp%
6175dbb105fc25903e800273f7e980c0553060858a68glennrp*/
6176991d11dd9c33e65872778b81aff1347cd2878154glennrpstatic MagickBooleanType OptimizePNGColormap(Image *image, IndexPacket
6177991d11dd9c33e65872778b81aff1347cd2878154glennrp     *ping_plte_map, IndexPacket *opacity)
6178dbb105fc25903e800273f7e980c0553060858a68glennrp{
6179dbb105fc25903e800273f7e980c0553060858a68glennrp  int
6180dbb105fc25903e800273f7e980c0553060858a68glennrp    k;
6181dbb105fc25903e800273f7e980c0553060858a68glennrp
6182dbb105fc25903e800273f7e980c0553060858a68glennrp  ssize_t
6183dbb105fc25903e800273f7e980c0553060858a68glennrp    j,
6184dbb105fc25903e800273f7e980c0553060858a68glennrp    new_number_colors,
6185dbb105fc25903e800273f7e980c0553060858a68glennrp    number_colors,
6186dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6187dbb105fc25903e800273f7e980c0553060858a68glennrp
6188dbb105fc25903e800273f7e980c0553060858a68glennrp  register const IndexPacket
6189dbb105fc25903e800273f7e980c0553060858a68glennrp    *indexes;
6190dbb105fc25903e800273f7e980c0553060858a68glennrp
6191dbb105fc25903e800273f7e980c0553060858a68glennrp  register const PixelPacket
6192dbb105fc25903e800273f7e980c0553060858a68glennrp    *p;
6193dbb105fc25903e800273f7e980c0553060858a68glennrp
6194dbb105fc25903e800273f7e980c0553060858a68glennrp  IndexPacket
6195dbb105fc25903e800273f7e980c0553060858a68glennrp    top_used;
6196dbb105fc25903e800273f7e980c0553060858a68glennrp
6197991d11dd9c33e65872778b81aff1347cd2878154glennrp  MagickBooleanType
6198991d11dd9c33e65872778b81aff1347cd2878154glennrp    remap_needed;
6199991d11dd9c33e65872778b81aff1347cd2878154glennrp
6200dbb105fc25903e800273f7e980c0553060858a68glennrp  register ssize_t
6201dbb105fc25903e800273f7e980c0553060858a68glennrp    i,
6202dbb105fc25903e800273f7e980c0553060858a68glennrp    x;
6203dbb105fc25903e800273f7e980c0553060858a68glennrp
6204dbb105fc25903e800273f7e980c0553060858a68glennrp  unsigned char
6205991d11dd9c33e65872778b81aff1347cd2878154glennrp    marker[256],
6206dbb105fc25903e800273f7e980c0553060858a68glennrp    have_transparency;
6207dbb105fc25903e800273f7e980c0553060858a68glennrp
6208dbb105fc25903e800273f7e980c0553060858a68glennrp  /*
6209dbb105fc25903e800273f7e980c0553060858a68glennrp    Determine if colormap can be compressed.
6210dbb105fc25903e800273f7e980c0553060858a68glennrp  */
6211dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image != (Image *) NULL);
6212dbb105fc25903e800273f7e980c0553060858a68glennrp  assert(image->signature == MagickSignature);
6213991d11dd9c33e65872778b81aff1347cd2878154glennrp
6214991d11dd9c33e65872778b81aff1347cd2878154glennrp  remap_needed=MagickFalse;
6215991d11dd9c33e65872778b81aff1347cd2878154glennrp
6216dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->debug != MagickFalse)
6217dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6218747aad10b49e665a439b920009ed92cc08e58741glennrp      "    OptimizePNGColormap %s (%.20g colors)",image->filename,
6219dbb105fc25903e800273f7e980c0553060858a68glennrp      (double) image->colors);
6220991d11dd9c33e65872778b81aff1347cd2878154glennrp
6221991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->storage_class != PseudoClass)
6222dbb105fc25903e800273f7e980c0553060858a68glennrp    {
6223dbb105fc25903e800273f7e980c0553060858a68glennrp      if (image->debug != MagickFalse)
6224dbb105fc25903e800273f7e980c0553060858a68glennrp        {
6225dbb105fc25903e800273f7e980c0553060858a68glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6226991d11dd9c33e65872778b81aff1347cd2878154glennrp               "    Could not compress colormap: image is not PseudoClass");
6227dbb105fc25903e800273f7e980c0553060858a68glennrp        }
6228991d11dd9c33e65872778b81aff1347cd2878154glennrp      return(MagickTrue);
6229dbb105fc25903e800273f7e980c0553060858a68glennrp    }
6230991d11dd9c33e65872778b81aff1347cd2878154glennrp
6231991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->colors == 1)
6232991d11dd9c33e65872778b81aff1347cd2878154glennrp     return(MagickTrue);  /* Nothing to do */
6233991d11dd9c33e65872778b81aff1347cd2878154glennrp
6234991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image-> colors == 0 || image->colors > 256)
6235dbb105fc25903e800273f7e980c0553060858a68glennrp    {
6236991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (image->debug != MagickFalse)
6237991d11dd9c33e65872778b81aff1347cd2878154glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6238991d11dd9c33e65872778b81aff1347cd2878154glennrp               "    Could not compress colormap with %d",(int) image->colors);
6239991d11dd9c33e65872778b81aff1347cd2878154glennrp
6240991d11dd9c33e65872778b81aff1347cd2878154glennrp      return(MagickFalse);
6241dbb105fc25903e800273f7e980c0553060858a68glennrp    }
6242991d11dd9c33e65872778b81aff1347cd2878154glennrp
6243dbb105fc25903e800273f7e980c0553060858a68glennrp  /*
6244dbb105fc25903e800273f7e980c0553060858a68glennrp    Mark colors that are present.
6245dbb105fc25903e800273f7e980c0553060858a68glennrp  */
6246dbb105fc25903e800273f7e980c0553060858a68glennrp  number_colors=(ssize_t) image->colors;
6247dbb105fc25903e800273f7e980c0553060858a68glennrp  for (i=0; i < number_colors; i++)
6248dbb105fc25903e800273f7e980c0553060858a68glennrp  {
6249dbb105fc25903e800273f7e980c0553060858a68glennrp    marker[i]=MagickFalse;
6250dbb105fc25903e800273f7e980c0553060858a68glennrp    opacity[i]=OpaqueOpacity;
6251dbb105fc25903e800273f7e980c0553060858a68glennrp  }
6252991d11dd9c33e65872778b81aff1347cd2878154glennrp
6253dbb105fc25903e800273f7e980c0553060858a68glennrp  top_used=0;
6254dbb105fc25903e800273f7e980c0553060858a68glennrp  for (y=0; y < (ssize_t) image->rows; y++)
6255dbb105fc25903e800273f7e980c0553060858a68glennrp  {
6256dbb105fc25903e800273f7e980c0553060858a68glennrp    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
6257991d11dd9c33e65872778b81aff1347cd2878154glennrp
6258dbb105fc25903e800273f7e980c0553060858a68glennrp    if (p == (const PixelPacket *) NULL)
6259dbb105fc25903e800273f7e980c0553060858a68glennrp      break;
6260991d11dd9c33e65872778b81aff1347cd2878154glennrp
6261dbb105fc25903e800273f7e980c0553060858a68glennrp    indexes=GetVirtualIndexQueue(image);
6262991d11dd9c33e65872778b81aff1347cd2878154glennrp
6263dbb105fc25903e800273f7e980c0553060858a68glennrp    if (image->matte != MagickFalse)
6264dbb105fc25903e800273f7e980c0553060858a68glennrp      for (x=0; x < (ssize_t) image->columns; x++)
6265dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6266991d11dd9c33e65872778b81aff1347cd2878154glennrp        i=(int) indexes[x];
6267991d11dd9c33e65872778b81aff1347cd2878154glennrp        marker[i]=MagickTrue;
6268991d11dd9c33e65872778b81aff1347cd2878154glennrp        opacity[i]=GetOpacityPixelComponent(p);
6269991d11dd9c33e65872778b81aff1347cd2878154glennrp
6270991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (i > top_used)
6271991d11dd9c33e65872778b81aff1347cd2878154glennrp           top_used=i;
6272dbb105fc25903e800273f7e980c0553060858a68glennrp        p++;
6273dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6274991d11dd9c33e65872778b81aff1347cd2878154glennrp
6275dbb105fc25903e800273f7e980c0553060858a68glennrp    else
6276dbb105fc25903e800273f7e980c0553060858a68glennrp      for (x=0; x < (ssize_t) image->columns; x++)
6277dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6278991d11dd9c33e65872778b81aff1347cd2878154glennrp        i=(int) indexes[x];
6279991d11dd9c33e65872778b81aff1347cd2878154glennrp        marker[i]=MagickTrue;
6280991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (i > top_used)
6281991d11dd9c33e65872778b81aff1347cd2878154glennrp           top_used=i;
6282dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6283dbb105fc25903e800273f7e980c0553060858a68glennrp  }
6284dbb105fc25903e800273f7e980c0553060858a68glennrp
6285dbb105fc25903e800273f7e980c0553060858a68glennrp  /*
6286dbb105fc25903e800273f7e980c0553060858a68glennrp    Mark background color, first occurrence if more than one.
6287dbb105fc25903e800273f7e980c0553060858a68glennrp  */
6288dbb105fc25903e800273f7e980c0553060858a68glennrp  for (i=0; i < number_colors; i++)
6289dbb105fc25903e800273f7e980c0553060858a68glennrp  {
6290dbb105fc25903e800273f7e980c0553060858a68glennrp    if (IsColorEqual(image->colormap+i,&image->background_color))
6291dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6292dbb105fc25903e800273f7e980c0553060858a68glennrp        marker[i]=MagickTrue;
6293dbb105fc25903e800273f7e980c0553060858a68glennrp        break;
6294dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6295dbb105fc25903e800273f7e980c0553060858a68glennrp  }
6296dbb105fc25903e800273f7e980c0553060858a68glennrp
6297dbb105fc25903e800273f7e980c0553060858a68glennrp  /*
6298dbb105fc25903e800273f7e980c0553060858a68glennrp    Unmark duplicates.
6299dbb105fc25903e800273f7e980c0553060858a68glennrp  */
6300dbb105fc25903e800273f7e980c0553060858a68glennrp  for (i=0; i < number_colors-1; i++)
6301dbb105fc25903e800273f7e980c0553060858a68glennrp    if (marker[i])
6302dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6303dbb105fc25903e800273f7e980c0553060858a68glennrp        for (j=i+1; j < number_colors; j++)
6304dbb105fc25903e800273f7e980c0553060858a68glennrp          if ((opacity[i] == opacity[j]) &&
6305dbb105fc25903e800273f7e980c0553060858a68glennrp              (IsColorEqual(image->colormap+i,image->colormap+j)))
6306dbb105fc25903e800273f7e980c0553060858a68glennrp            {
6307dbb105fc25903e800273f7e980c0553060858a68glennrp              marker[j]=MagickFalse;
6308dbb105fc25903e800273f7e980c0553060858a68glennrp            }
6309dbb105fc25903e800273f7e980c0553060858a68glennrp       }
6310991d11dd9c33e65872778b81aff1347cd2878154glennrp
6311dbb105fc25903e800273f7e980c0553060858a68glennrp  /*
6312dbb105fc25903e800273f7e980c0553060858a68glennrp    Count colors that still remain.
6313dbb105fc25903e800273f7e980c0553060858a68glennrp  */
6314dbb105fc25903e800273f7e980c0553060858a68glennrp  have_transparency=MagickFalse;
6315dbb105fc25903e800273f7e980c0553060858a68glennrp  new_number_colors=0;
6316991d11dd9c33e65872778b81aff1347cd2878154glennrp
6317dbb105fc25903e800273f7e980c0553060858a68glennrp  for (i=0; i < number_colors; i++)
6318dbb105fc25903e800273f7e980c0553060858a68glennrp    if (marker[i])
6319dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6320dbb105fc25903e800273f7e980c0553060858a68glennrp        new_number_colors++;
6321dbb105fc25903e800273f7e980c0553060858a68glennrp        if (opacity[i] != OpaqueOpacity)
6322dbb105fc25903e800273f7e980c0553060858a68glennrp          have_transparency=MagickTrue;
6323dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6324991d11dd9c33e65872778b81aff1347cd2878154glennrp
6325dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->debug != MagickFalse)
6326dbb105fc25903e800273f7e980c0553060858a68glennrp    {
6327dbb105fc25903e800273f7e980c0553060858a68glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6328991d11dd9c33e65872778b81aff1347cd2878154glennrp          "    new_number_colors in OptimizePNGColormap=%d",
6329991d11dd9c33e65872778b81aff1347cd2878154glennrp          (int) new_number_colors);
6330dbb105fc25903e800273f7e980c0553060858a68glennrp    }
6331991d11dd9c33e65872778b81aff1347cd2878154glennrp
6332dbb105fc25903e800273f7e980c0553060858a68glennrp  if ((!have_transparency || (marker[0] &&
6333dbb105fc25903e800273f7e980c0553060858a68glennrp      (opacity[0] == (Quantum) TransparentOpacity)))
6334dbb105fc25903e800273f7e980c0553060858a68glennrp      && (new_number_colors == number_colors))
6335dbb105fc25903e800273f7e980c0553060858a68glennrp    {
6336dbb105fc25903e800273f7e980c0553060858a68glennrp      /*
6337dbb105fc25903e800273f7e980c0553060858a68glennrp        No duplicate or unused entries, and transparency-swap not needed.
6338dbb105fc25903e800273f7e980c0553060858a68glennrp      */
6339991d11dd9c33e65872778b81aff1347cd2878154glennrp
6340dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
6341dbb105fc25903e800273f7e980c0553060858a68glennrp    }
6342dbb105fc25903e800273f7e980c0553060858a68glennrp
6343991d11dd9c33e65872778b81aff1347cd2878154glennrp  remap_needed=MagickTrue;
6344dbb105fc25903e800273f7e980c0553060858a68glennrp
6345dbb105fc25903e800273f7e980c0553060858a68glennrp  /*
6346dbb105fc25903e800273f7e980c0553060858a68glennrp    Eliminate unused colormap entries.
6347dbb105fc25903e800273f7e980c0553060858a68glennrp  */
6348dbb105fc25903e800273f7e980c0553060858a68glennrp  for (i=0; i < number_colors; i++)
6349991d11dd9c33e65872778b81aff1347cd2878154glennrp   ping_plte_map[i]=i;
6350991d11dd9c33e65872778b81aff1347cd2878154glennrp
6351dbb105fc25903e800273f7e980c0553060858a68glennrp  k=0;
6352dbb105fc25903e800273f7e980c0553060858a68glennrp  for (i=0; i < number_colors; i++)
6353dbb105fc25903e800273f7e980c0553060858a68glennrp  {
6354dbb105fc25903e800273f7e980c0553060858a68glennrp    if (marker[i])
6355dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6356991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_plte_map[i]=(IndexPacket) k;
6357dbb105fc25903e800273f7e980c0553060858a68glennrp        for (j=i+1; j < number_colors; j++)
6358dbb105fc25903e800273f7e980c0553060858a68glennrp        {
6359dbb105fc25903e800273f7e980c0553060858a68glennrp          if ((opacity[i] == opacity[j]) &&
6360dbb105fc25903e800273f7e980c0553060858a68glennrp              (IsColorEqual(image->colormap+i,image->colormap+j)))
6361dbb105fc25903e800273f7e980c0553060858a68glennrp            {
6362991d11dd9c33e65872778b81aff1347cd2878154glennrp              ping_plte_map[j]=(IndexPacket) k;
6363dbb105fc25903e800273f7e980c0553060858a68glennrp               marker[j]=MagickFalse;
6364dbb105fc25903e800273f7e980c0553060858a68glennrp            }
6365dbb105fc25903e800273f7e980c0553060858a68glennrp        }
6366dbb105fc25903e800273f7e980c0553060858a68glennrp        k++;
6367dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6368dbb105fc25903e800273f7e980c0553060858a68glennrp  }
6369991d11dd9c33e65872778b81aff1347cd2878154glennrp
6370dbb105fc25903e800273f7e980c0553060858a68glennrp  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
6371dbb105fc25903e800273f7e980c0553060858a68glennrp    {
6372dbb105fc25903e800273f7e980c0553060858a68glennrp      /*
6373dbb105fc25903e800273f7e980c0553060858a68glennrp        Move the first transparent color to palette entry 0.
6374dbb105fc25903e800273f7e980c0553060858a68glennrp      */
6375dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=1; i < number_colors; i++)
6376dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6377dbb105fc25903e800273f7e980c0553060858a68glennrp        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
6378dbb105fc25903e800273f7e980c0553060858a68glennrp          {
6379dbb105fc25903e800273f7e980c0553060858a68glennrp            for (j=0; j < number_colors; j++)
6380dbb105fc25903e800273f7e980c0553060858a68glennrp            {
6381991d11dd9c33e65872778b81aff1347cd2878154glennrp              if (ping_plte_map[j] == 0)
6382991d11dd9c33e65872778b81aff1347cd2878154glennrp               ping_plte_map[j]=ping_plte_map[i];
6383991d11dd9c33e65872778b81aff1347cd2878154glennrp              else if (ping_plte_map[j] == ping_plte_map[i])
6384991d11dd9c33e65872778b81aff1347cd2878154glennrp                ping_plte_map[j]=0;
6385dbb105fc25903e800273f7e980c0553060858a68glennrp            }
6386dbb105fc25903e800273f7e980c0553060858a68glennrp            remap_needed=MagickTrue;
6387dbb105fc25903e800273f7e980c0553060858a68glennrp            break;
6388dbb105fc25903e800273f7e980c0553060858a68glennrp          }
6389dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6390dbb105fc25903e800273f7e980c0553060858a68glennrp   }
6391dbb105fc25903e800273f7e980c0553060858a68glennrp
6392991d11dd9c33e65872778b81aff1347cd2878154glennrp  return(MagickTrue);
6393991d11dd9c33e65872778b81aff1347cd2878154glennrp}
6394991d11dd9c33e65872778b81aff1347cd2878154glennrp#endif /* PNG_SORT_PALETTE */
6395991d11dd9c33e65872778b81aff1347cd2878154glennrp
6396991d11dd9c33e65872778b81aff1347cd2878154glennrp/*
6397991d11dd9c33e65872778b81aff1347cd2878154glennrp * Temporary wrapper for OptimizePNGColormap
6398991d11dd9c33e65872778b81aff1347cd2878154glennrp */
6399991d11dd9c33e65872778b81aff1347cd2878154glennrpstatic MagickBooleanType CompressColormapTransFirst(Image *image)
6400991d11dd9c33e65872778b81aff1347cd2878154glennrp{
6401991d11dd9c33e65872778b81aff1347cd2878154glennrp#if defined(PNG_SORT_PALETTE)
6402991d11dd9c33e65872778b81aff1347cd2878154glennrp  register ssize_t
6403991d11dd9c33e65872778b81aff1347cd2878154glennrp      i;
6404991d11dd9c33e65872778b81aff1347cd2878154glennrp
6405991d11dd9c33e65872778b81aff1347cd2878154glennrp  IndexPacket
6406991d11dd9c33e65872778b81aff1347cd2878154glennrp      opacity[256],
6407991d11dd9c33e65872778b81aff1347cd2878154glennrp      ping_plte_map[256];
6408991d11dd9c33e65872778b81aff1347cd2878154glennrp
6409991d11dd9c33e65872778b81aff1347cd2878154glennrp  for (i=0; i<256; i++)
6410991d11dd9c33e65872778b81aff1347cd2878154glennrp  {
6411991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_plte_map[i]=i;
6412991d11dd9c33e65872778b81aff1347cd2878154glennrp    opacity[i]=0;
6413991d11dd9c33e65872778b81aff1347cd2878154glennrp  }
6414991d11dd9c33e65872778b81aff1347cd2878154glennrp
6415991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (OptimizePNGColormap(image, ping_plte_map, opacity) == MagickFalse)
6416991d11dd9c33e65872778b81aff1347cd2878154glennrp    return MagickFalse;
6417991d11dd9c33e65872778b81aff1347cd2878154glennrp
6418991d11dd9c33e65872778b81aff1347cd2878154glennrp  else
6419991d11dd9c33e65872778b81aff1347cd2878154glennrp  {
6420991d11dd9c33e65872778b81aff1347cd2878154glennrp    ExceptionInfo
6421991d11dd9c33e65872778b81aff1347cd2878154glennrp      *exception;
6422991d11dd9c33e65872778b81aff1347cd2878154glennrp
6423991d11dd9c33e65872778b81aff1347cd2878154glennrp    register IndexPacket
6424991d11dd9c33e65872778b81aff1347cd2878154glennrp      *pixels;
6425991d11dd9c33e65872778b81aff1347cd2878154glennrp
6426991d11dd9c33e65872778b81aff1347cd2878154glennrp    PixelPacket
6427991d11dd9c33e65872778b81aff1347cd2878154glennrp      colormap[256];
6428991d11dd9c33e65872778b81aff1347cd2878154glennrp
6429991d11dd9c33e65872778b81aff1347cd2878154glennrp    register PixelPacket
6430991d11dd9c33e65872778b81aff1347cd2878154glennrp      *q;
6431991d11dd9c33e65872778b81aff1347cd2878154glennrp
6432991d11dd9c33e65872778b81aff1347cd2878154glennrp    MagickBooleanType
6433991d11dd9c33e65872778b81aff1347cd2878154glennrp      remap_needed;
6434991d11dd9c33e65872778b81aff1347cd2878154glennrp
6435991d11dd9c33e65872778b81aff1347cd2878154glennrp    size_t
6436991d11dd9c33e65872778b81aff1347cd2878154glennrp      ping_number_colors;
6437991d11dd9c33e65872778b81aff1347cd2878154glennrp
6438991d11dd9c33e65872778b81aff1347cd2878154glennrp    ssize_t
6439991d11dd9c33e65872778b81aff1347cd2878154glennrp      j,
6440991d11dd9c33e65872778b81aff1347cd2878154glennrp      y;
6441991d11dd9c33e65872778b81aff1347cd2878154glennrp
6442991d11dd9c33e65872778b81aff1347cd2878154glennrp    register ssize_t
6443991d11dd9c33e65872778b81aff1347cd2878154glennrp      x;
6444991d11dd9c33e65872778b81aff1347cd2878154glennrp
6445991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_number_colors=(size_t) 0;
6446991d11dd9c33e65872778b81aff1347cd2878154glennrp    remap_needed = MagickFalse;
6447991d11dd9c33e65872778b81aff1347cd2878154glennrp
6448991d11dd9c33e65872778b81aff1347cd2878154glennrp    for (i=0; i<image->colors; i++)
6449dbb105fc25903e800273f7e980c0553060858a68glennrp    {
6450991d11dd9c33e65872778b81aff1347cd2878154glennrp      colormap[ping_plte_map[i]] = image->colormap[i];
6451dbb105fc25903e800273f7e980c0553060858a68glennrp
6452991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_plte_map[i] != i)
6453991d11dd9c33e65872778b81aff1347cd2878154glennrp        remap_needed = MagickTrue;
6454dbb105fc25903e800273f7e980c0553060858a68glennrp
6455991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_plte_map[i] >= ping_number_colors)
6456991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_number_colors=ping_plte_map[i]+1;
6457991d11dd9c33e65872778b81aff1347cd2878154glennrp    }
6458dbb105fc25903e800273f7e980c0553060858a68glennrp
6459991d11dd9c33e65872778b81aff1347cd2878154glennrp    /* TO DO: add background color if necessary */
6460dbb105fc25903e800273f7e980c0553060858a68glennrp
6461991d11dd9c33e65872778b81aff1347cd2878154glennrp    if (remap_needed == MagickFalse)
6462991d11dd9c33e65872778b81aff1347cd2878154glennrp       return MagickTrue;
6463991d11dd9c33e65872778b81aff1347cd2878154glennrp
6464991d11dd9c33e65872778b81aff1347cd2878154glennrp    /*
6465dbb105fc25903e800273f7e980c0553060858a68glennrp        Remap pixels.
6466991d11dd9c33e65872778b81aff1347cd2878154glennrp    */
6467991d11dd9c33e65872778b81aff1347cd2878154glennrp    exception=(&image->exception);
6468991d11dd9c33e65872778b81aff1347cd2878154glennrp    for (y=0; y < (ssize_t) image->rows; y++)
6469991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
6470991d11dd9c33e65872778b81aff1347cd2878154glennrp      q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
6471991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (q == (PixelPacket *) NULL)
6472991d11dd9c33e65872778b81aff1347cd2878154glennrp        break;
6473991d11dd9c33e65872778b81aff1347cd2878154glennrp      pixels=GetAuthenticIndexQueue(image);
6474991d11dd9c33e65872778b81aff1347cd2878154glennrp      for (x=0; x < (ssize_t) image->columns; x++)
6475dbb105fc25903e800273f7e980c0553060858a68glennrp      {
6476991d11dd9c33e65872778b81aff1347cd2878154glennrp        j=(int) pixels[x];
6477991d11dd9c33e65872778b81aff1347cd2878154glennrp        pixels[x]=(IndexPacket) ping_plte_map[j];
6478dbb105fc25903e800273f7e980c0553060858a68glennrp      }
6479991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (SyncAuthenticPixels(image,exception) == MagickFalse)
6480991d11dd9c33e65872778b81aff1347cd2878154glennrp        break;
6481dbb105fc25903e800273f7e980c0553060858a68glennrp    }
6482dbb105fc25903e800273f7e980c0553060858a68glennrp
6483991d11dd9c33e65872778b81aff1347cd2878154glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6484991d11dd9c33e65872778b81aff1347cd2878154glennrp        "    After OptimizePNGColormap:");
6485991d11dd9c33e65872778b81aff1347cd2878154glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6486991d11dd9c33e65872778b81aff1347cd2878154glennrp        "    i  plte_map  (red,green,blue,opacity)");
6487991d11dd9c33e65872778b81aff1347cd2878154glennrp    for (i=0; i < image->colors; i++)
6488991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
6489991d11dd9c33e65872778b81aff1347cd2878154glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6490991d11dd9c33e65872778b81aff1347cd2878154glennrp          "    %d  %d (%d,%d,%d,%d)",
6491991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) i,
6492991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) ping_plte_map[i],
6493991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) image->colormap[i].red,
6494991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) image->colormap[i].green,
6495991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) image->colormap[i].blue,
6496991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) opacity[ping_plte_map[i]]);
6497991d11dd9c33e65872778b81aff1347cd2878154glennrp    }
6498dbb105fc25903e800273f7e980c0553060858a68glennrp
6499dbb105fc25903e800273f7e980c0553060858a68glennrp
6500991d11dd9c33e65872778b81aff1347cd2878154glennrp    for (i=0; i<image->colors; i++)
6501991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
6502991d11dd9c33e65872778b81aff1347cd2878154glennrp      image->colormap[i] = colormap[i];
6503991d11dd9c33e65872778b81aff1347cd2878154glennrp    }
6504dbb105fc25903e800273f7e980c0553060858a68glennrp
6505991d11dd9c33e65872778b81aff1347cd2878154glennrp    image->colors = ping_number_colors;
6506991d11dd9c33e65872778b81aff1347cd2878154glennrp
6507991d11dd9c33e65872778b81aff1347cd2878154glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6508991d11dd9c33e65872778b81aff1347cd2878154glennrp        "    After Remap:");
6509991d11dd9c33e65872778b81aff1347cd2878154glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6510991d11dd9c33e65872778b81aff1347cd2878154glennrp        "    i   (red,green,blue,opacity)");
6511991d11dd9c33e65872778b81aff1347cd2878154glennrp    for (i=0; i < image->colors; i++)
6512991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
6513991d11dd9c33e65872778b81aff1347cd2878154glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6514991d11dd9c33e65872778b81aff1347cd2878154glennrp          "    %d  (%d,%d,%d,%d)",
6515991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) i,
6516991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) image->colormap[i].red,
6517991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) image->colormap[i].green,
6518991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) image->colormap[i].blue,
6519991d11dd9c33e65872778b81aff1347cd2878154glennrp           (int) opacity[i]);
6520991d11dd9c33e65872778b81aff1347cd2878154glennrp    }
65216f351cf4e770fcb0086207bd5dd7178132a0c15bglennrp
6522991d11dd9c33e65872778b81aff1347cd2878154glennrp    return MagickTrue;
6523991d11dd9c33e65872778b81aff1347cd2878154glennrp  }
6524991d11dd9c33e65872778b81aff1347cd2878154glennrp#else
6525991d11dd9c33e65872778b81aff1347cd2878154glennrp  image=image;
6526991d11dd9c33e65872778b81aff1347cd2878154glennrp  return MagickTrue;
6527991d11dd9c33e65872778b81aff1347cd2878154glennrp#endif /* PNG_SORT_PALETTE */
6528747aad10b49e665a439b920009ed92cc08e58741glennrp}
6529747aad10b49e665a439b920009ed92cc08e58741glennrp
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6549cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6550cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6551e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6552e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
65535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     palette;
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
65585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
65595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
65605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
65685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
65695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
65705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6571bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
6575991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6576991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6577991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
65955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_bit_depth,
65965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
65975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
65985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
65995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
66005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
66015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
66045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
66055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6607bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6616f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
66205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=0,
66215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
66225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
66235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
66245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
66255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
66265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
66275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
66285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
66295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
66305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
66315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
66325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
66335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
66345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
66355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
66365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
66375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6638991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
6639991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
6640991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
6641991d11dd9c33e65872778b81aff1347cd2878154glennrp
6642ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_colors=image->colors;
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=image->depth;
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_matte=image->matte;
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->IsPalette=image->storage_class == PseudoClass &&
66501449ea221d08431e12b667713077313a49000dc8cristy    image_colors <= 256 && !IsOpaqueImage(image,&image->exception);
6651991d11dd9c33e65872778b81aff1347cd2878154glennrp#if 0
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->optimize=image_info->type == OptimizeType;
6653991d11dd9c33e65872778b81aff1347cd2878154glennrp#else
6654991d11dd9c33e65872778b81aff1347cd2878154glennrp  mng_info->optimize = MagickFalse;
6655991d11dd9c33e65872778b81aff1347cd2878154glennrp#endif
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6690f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
67074e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
67084e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6723e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6725e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6727e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6729e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth=%.20g",(double) image->depth);
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6731e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    requested PNG image_depth=%.20g",(double) image->depth);
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
67345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution);
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution);
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6758991d11dd9c33e65872778b81aff1347cd2878154glennrp
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_UNKNOWN;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) image->x_resolution;
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) image->y_resolution;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6765991d11dd9c33e65872778b81aff1347cd2878154glennrp
6766991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up pHYs chunk");
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x || image->page.y)
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (png_int_32) image->page.y, 0);
6777991d11dd9c33e65872778b81aff1347cd2878154glennrp
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up oFFs chunk");
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6783a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
6784a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6786a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
6787a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
6788a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
6789a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
6790a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
6791a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
6792a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
6793a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
6794a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
6795a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
6796a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
6797a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
6798a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
6799a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
6800a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
6801a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
6802a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
6803a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
6804a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp      }
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Setting up bKGd chunk");
6809991d11dd9c33e65872778b81aff1347cd2878154glennrp      ping_have_bKGD = MagickTrue;
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
681579f9995ecaa0e0daae607e9e88f257706730084dcristy  if ((mng_info->write_png_colortype-1) == PNG_COLOR_TYPE_PALETTE)
681679f9995ecaa0e0daae607e9e88f257706730084dcristy    mng_info->write_png8=MagickTrue;
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
68205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_bit_depth=8;
68215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: make this a function cause it's used twice, except
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             for reducing the sample depth from 8. */
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          QuantizeInfo
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantize_info;
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6829bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
6830a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp             number_colors;
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image->storage_class == DirectClass) || (number_colors > 256))
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GetQuantizeInfo(&quantize_info);
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MagickFalse ? MagickTrue : MagickFalse;
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                256UL);
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) QuantizeImage(&quantize_info,image);
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors=image_colors;
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) SyncImage(image);
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6845e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    Colors quantized to %.20g",(double) number_colors);
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
68485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Set image palette.
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
68525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (CompressColormapTransFirst(image) == MagickFalse)
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
685598156a3a465a004545e39434c63052b955a74d1cglennrp          number_colors=image->colors;
6856a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          image_colors=number_colors;
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_color *) AcquireQuantumMemory(257,
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*palette));
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (palette == (png_color *) NULL)
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6863a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                "  Setting up PLTE chunk with %d colors (%d)",
6864a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                (int) number_colors, (int) image_colors);
6865bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) number_colors; i++)
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %3ld (%3d,%3d,%3d)",
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %5ld (%5d,%5d,%5d)",
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6877f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                (long) i,palette[i].red,palette[i].green,palette[i].blue);
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors++;
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_colorp) RelinquishMagickMemory(palette);
68895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            image_depth=ping_bit_depth;
68905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              int
68975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                trans_alpha[256];
68985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
6903bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
69045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 trans_alpha[i]=255;
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
6906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register const PixelPacket
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *p;
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
691112aea8120076c564d99e5b0f91a12aab268c4910glennrp                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (PixelPacket *) NULL)
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
6914bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
691812aea8120076c564d99e5b0f91a12aab268c4910glennrp                      trans_alpha[(ssize_t) number_colors-1]=(png_byte) (255-
6919ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
6924bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
69255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if (trans_alpha[i] != 255)
69265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=(unsigned short) (i+1);
69275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
69295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 png_set_invalid(ping, ping_info, PNG_INFO_tRNS);
69305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping, ping_info, PNG_INFO_tRNS))
69315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
69325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
69335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                {
69345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  for (i=0; i<256; i++)
69355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                     ping_trans_alpha[i]=(png_byte) trans_alpha[i];
69365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                }
69375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6938991d11dd9c33e65872778b81aff1347cd2878154glennrp              ping_have_tRNS=MagickTrue;
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Identify which colormap entry is the background color.
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
6943bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
69445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (IsPNGColorEqual(ping_background,image->colormap[i]))
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
69465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_background.index=(png_byte) i;
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
69565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
69615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
6969b905e45f528487c0e1c2a28b86b89f8ed86433a0cristy          image_matte=MagickFalse;
69705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
69715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "Selecting PNG colortype");
69795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) ((matte == MagickTrue)?
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         "Selected PNG colortype=%d",ping_color_type);
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
70145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
70155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB ||
70165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
70175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=8;
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
70275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (ping_bit_depth < (int)mng_info->write_png_depth)
70285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth = mng_info->write_png_depth;
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
703435ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
70355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
70360f111984738842d27d04aed2a3f823d82a943506glennrp
70370f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
70380f111984738842d27d04aed2a3f823d82a943506glennrp           {
70390f111984738842d27d04aed2a3f823d82a943506glennrp              /* DO SOMETHING */
70400f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
70410f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
70420f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
70430f111984738842d27d04aed2a3f823d82a943506glennrp           }
70440f111984738842d27d04aed2a3f823d82a943506glennrp
70450f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
70460f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70470f111984738842d27d04aed2a3f823d82a943506glennrp                  "  SyncImage.2.");
704835ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
70495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7054e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "    Number of colors: %.20g",(double) image_colors);
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                "    Tentative PNG bit depth: %d",ping_bit_depth);
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
70605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               old_bit_depth=ping_bit_depth;
70615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               if (ping_bit_depth < (int)mng_info->write_png_depth)
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
70635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth = mng_info->write_png_depth;
70645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth > 8)
70655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth = 8;
70665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth != (int) old_bit_depth)
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7070e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                           "    Colors increased to %.20g",(double)
7071f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                           image_colors);
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7081e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7083e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7085e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7087e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (matte && (mng_info->optimize || mng_info->IsPalette))
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
70965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
7097bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7102bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
71065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7115bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7120bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (x != 0)
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7129bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((y == (ssize_t) image->rows) && (x == (ssize_t) image->columns))
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
71325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
71355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type&=0x03;
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
71435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 8)
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
71455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 4)
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
71475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 2)
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
71495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 1)
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
71515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.red=(png_uint_16)
7152ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetRedPixelComponent(p)) & mask);
71535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.green=(png_uint_16)
7154ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetGreenPixelComponent(p)) & mask);
71555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.blue=(png_uint_16)
7156ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetBluePixelComponent(p)) & mask);
71575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.gray=(png_uint_16)
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
71595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.index=(png_byte)
716046f08209f719f4adeea742c45873c2714e80cdb9cristy            (ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))));
7161991d11dd9c33e65872778b81aff1347cd2878154glennrp          ping_have_tRNS=MagickTrue;
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
7169bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p) == 0)
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for multiple
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent colors.  */
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                semitransparency. */
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               else
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p))
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7200217484eb7236f4f3527af0feb39a6dc19a3302fecristy            if (x >= 0)
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7203217484eb7236f4f3527af0feb39a6dc19a3302fecristy          if (x >= 0)
72045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
72065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
72085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
72115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
72125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
72135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
72145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
72195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((mng_info->optimize || mng_info->IsPalette) &&
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
722535ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
72279c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
72305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
72325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray*=0x0101;
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
723735ef824baa82511126ff0072ae30eee0da9c05a3cristy          image_colors=one << image_depth;
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
72395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
72425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
72435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
72475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
724835ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7249bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
72505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (mng_info->optimize && ping_color_type ==
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
72799c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
72819c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
72839c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
729217a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
729317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
729417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
729517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
73015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
73049c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
73059c1eb0729653219b9da9037e044501a6dce79d10glennrp                if (logging)
73069c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73079c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->optimize)
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (CompressColormapTransFirst(image) == MagickFalse)
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       ThrowWriterException(ResourceLimitError,
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                            "MemoryAllocationFailed");
731698156a3a465a004545e39434c63052b955a74d1cglennrp                    number_colors=image->colors;
7317a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    image_colors=number_colors;
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_color *) AcquireQuantumMemory(257,
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sizeof(*palette));
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (palette == (png_color *) NULL)
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
7324bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging)
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
733298156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
733398156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_colorp) RelinquishMagickMemory(palette);
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7340befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
7341befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
7342befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
73435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
7344befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
7345befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
73465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
73485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const PixelPacket
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p;
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[256];
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const IndexPacket
73615c6f789db7a30bad01ace12b09ad9cd471339e94cristy                *packet_indexes;
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
7367bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[i]=256;
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
7370bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (const PixelPacket *) NULL)
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
73755c6f789db7a30bad01ace12b09ad9cd471339e94cristy                packet_indexes=GetVirtualIndexQueue(image);
7376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      IndexPacket
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        packet_index;
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73835c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      packet_index=packet_indexes[x];
7384a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                      if((size_t) packet_index >= number_colors)
7385a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                        (void) LogMagickEvent(CoderEvent, GetMagickModule(),
7386a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                        "packet_index=%d, number_colors=%d",
7387a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                        (int) packet_index, (int) number_colors);
7388bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      assert((size_t) packet_index < number_colors);
7389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      if (trans[(ssize_t) packet_index] != 256)
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
7391bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                          if (trans[(ssize_t) packet_index] != (png_byte) (255-
7392ce70c17bb6433add2eb069515a4f3105989e0662cristy                             ScaleQuantumToChar(GetOpacityPixelComponent(p))))
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
73945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                              ping_color_type=(png_byte)
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                PNG_COLOR_TYPE_RGB_ALPHA;
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              break;
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
7399bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans[(ssize_t) packet_index]=(png_byte) (255-
7400ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
74045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
74065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=0;
74075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
74085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_PLTE);
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->IsPalette=MagickFalse;
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) SyncImage(image);
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (logging)
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "    Cannot write image as indexed PNG, writing RGBA.");
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
74175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7419bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] == 256)
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    trans[i]=255;
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] != 255)
74245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_num_trans=(unsigned short) (i+1);
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
74275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
74285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
74295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
74305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
74315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
74329c1eb0729653219b9da9037e044501a6dce79d10glennrp                {
74339c1eb0729653219b9da9037e044501a6dce79d10glennrp                  for (i=0; i < (ssize_t) number_colors; i++)
74349c1eb0729653219b9da9037e044501a6dce79d10glennrp                      ping_trans_alpha[i]=(png_byte) trans[i];
74359c1eb0729653219b9da9037e044501a6dce79d10glennrp                }
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
74465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
74475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
74485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
74495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
74565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
746235ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
746335ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
746435ef824baa82511126ff0072ae30eee0da9c05a3cristy
746522ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7468a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Setting up bKGD chunk");
7474991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
74775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
747917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
748017a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
748117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
748217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
748317a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
748417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
748517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7486bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
748717a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
748817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
748917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
749017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7491a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
7492a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
749317a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
749417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
749517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
749617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
749717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        if (logging)
7498a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        {
749917a1485544c62993fc7a94e343c87fed5f3e6407glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
750017a1485544c62993fc7a94e343c87fed5f3e6407glennrp            "  Setting up bKGD chunk with index=%d",(int) i);
7501a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        }
7502a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7503991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (i < number_colors)
7504a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        {
7505991d11dd9c33e65872778b81aff1347cd2878154glennrp          ping_have_bKGD = MagickTrue;
7506a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (logging)
7507a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
7508a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7509a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp              "     background   =(%d,%d,%d)",
7510a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    (int) ping_background.red,
7511a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    (int) ping_background.green,
7512a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    (int) ping_background.blue);
7513a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
7514a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        }
751517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7516a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        else
7517991d11dd9c33e65872778b81aff1347cd2878154glennrp          ping_have_bKGD = MagickFalse;
751817a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
751917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up deflate compression");
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression buffer size: 32768");
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
75685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter=PNG_ALL_FILTERS;
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((quality % 10) != 5)
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
75855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
75865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_NO_FILTERS;
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_ALL_FILTERS;
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
76095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
7638e610a071534e448c46460a5aa39ede33bf56b329glennrp      (void) png_set_sRGB(ping,ping_info,(
7639e610a071534e448c46460a5aa39ede33bf56b329glennrp        PNG_RenderingIntent_from_Magick_RenderingIntent(
7640e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent)));
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
76945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
76955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
76965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
77015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
77055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
77075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
7708991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
77095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
77185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
77255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77283bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
77303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && !image->matte)
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
7737b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
7738b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7739b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7742991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (image->matte == MagickTrue)
7743e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
7744991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
7745991d11dd9c33e65872778b81aff1347cd2878154glennrp        if (ping_color_type != 3 || ping_num_trans > 0)
7746991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
7747e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
7748e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
77545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
77555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
77565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
77575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7758991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (ping_have_bKGD != MagickFalse)
7759991d11dd9c33e65872778b81aff1347cd2878154glennrp      png_set_bKGD(ping,ping_info,&ping_background);
7760991d11dd9c33e65872778b81aff1347cd2878154glennrp
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
7762991d11dd9c33e65872778b81aff1347cd2878154glennrp
7763991d11dd9c33e65872778b81aff1347cd2878154glennrp  if (ping_have_tRNS != MagickFalse)
7764991d11dd9c33e65872778b81aff1347cd2878154glennrp  {
7765991d11dd9c33e65872778b81aff1347cd2878154glennrp    if (logging)
7766991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
7767991d11dd9c33e65872778b81aff1347cd2878154glennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7768991d11dd9c33e65872778b81aff1347cd2878154glennrp           "Calling png_set_tRNS");
7769991d11dd9c33e65872778b81aff1347cd2878154glennrp    }
7770991d11dd9c33e65872778b81aff1347cd2878154glennrp
7771991d11dd9c33e65872778b81aff1347cd2878154glennrp    if (ping_color_type == 3)
7772991d11dd9c33e65872778b81aff1347cd2878154glennrp       (void) png_set_tRNS(ping, ping_info,
7773991d11dd9c33e65872778b81aff1347cd2878154glennrp              ping_trans_alpha,
7774991d11dd9c33e65872778b81aff1347cd2878154glennrp              ping_num_trans,
7775991d11dd9c33e65872778b81aff1347cd2878154glennrp              NULL);
7776991d11dd9c33e65872778b81aff1347cd2878154glennrp
7777991d11dd9c33e65872778b81aff1347cd2878154glennrp    else if (ping_color_type < 3)
7778991d11dd9c33e65872778b81aff1347cd2878154glennrp       (void) png_set_tRNS(ping, ping_info,
7779991d11dd9c33e65872778b81aff1347cd2878154glennrp              NULL,
7780991d11dd9c33e65872778b81aff1347cd2878154glennrp              0,
7781991d11dd9c33e65872778b81aff1347cd2878154glennrp              &ping_trans_color);
7782991d11dd9c33e65872778b81aff1347cd2878154glennrp  }
7783991d11dd9c33e65872778b81aff1347cd2878154glennrp
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
7787991d11dd9c33e65872778b81aff1347cd2878154glennrp
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77939c1eb0729653219b9da9037e044501a6dce79d10glennrp      unsigned char
77949c1eb0729653219b9da9037e044501a6dce79d10glennrp        chunk[14];
77959c1eb0729653219b9da9037e044501a6dce79d10glennrp
77969c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
77979c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGType(chunk,mng_vpAg);
77989c1eb0729653219b9da9037e044501a6dce79d10glennrp      LogPNGChunk((int) logging,mng_vpAg,9L);
77999c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+4,(png_uint_32) image->page.width);
78009c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+8,(png_uint_32) image->page.height);
78019c1eb0729653219b9da9037e044501a6dce79d10glennrp      chunk[12]=0;   /* unit = pixels */
78029c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlob(image,13,chunk);
78039c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
78079c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
78099c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
78113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
78123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
78153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
7818b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
7819b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
78207202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
78213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7822b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
7824b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7825b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
7826b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
7827b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7828b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
7830b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7831b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
7832b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7834b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (logging)
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7836b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7837b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
7838b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7839e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
78485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
78583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
78613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7863f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
78643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
78663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7867ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
7868ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
7869ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mng_info->optimize || mng_info->IsPalette ||
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
7881a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
7888bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
78893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7890a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
7891a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7892a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp              "    Writing row of pixels (0)");
7893a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
7906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
7917bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
7920b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7921b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7922b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
79425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7945bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
79463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
79505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
79513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
79523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
7958b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7959b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7960b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                     "    Writing GRAY PNG pixels (2)");
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7964b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7965b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7966b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (2)");
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7970b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7971b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7972b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (2)");
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
7988bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
79935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
80025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
8003b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
8004b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8005b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
8006b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                if (logging && y == 0)
8007b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8008b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (3)");
8009b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
80153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
8016b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            if (logging && y == 0)
8017b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8018b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "    Writing row of pixels (3)");
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
80265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
80275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging)
80303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8035bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
80363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8037e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            if (logging && y == 0)
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
80435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
80453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
80465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
8047b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
804807cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp                if (logging && y == 0)
8049b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8050b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "  Writing GRAY_ALPHA PNG pixels (4)");
8051b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
8052b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
8053b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
80553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
8057a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp              if (logging && y <= 2)
8058a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp              {
8059a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8060a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    "  Writing row of pixels (4)");
8061a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8062a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    "  png_pixels[0]=%d,png_pixels[1]=%d",
8063a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp                    (int)png_pixels[0],(int)png_pixels[1]);
8064a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp              }
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
80683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8076b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
8077b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8082b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8084e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
80853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8086e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
81475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
81485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
81695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
81725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
81873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  s[0]=(char) ping_bit_depth;
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
81993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8204f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
82233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
82273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
82453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               channel is present even if the image is fully opaque.
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               from the application programming interfaces.
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
82943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Allow all other PNG subformats to be requested via new
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "-define png:bit-depth -define png:color-type" options.
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
83023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
83133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
83153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  subsequent profiles from overwriting the preceding ones:
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
83213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
835773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
83613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
8365a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83769c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
83779c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
83789c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0 /* this does not work */
83809c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
83819c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,PaletteMatteType);
83829c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
83839c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,PaletteType);
83849c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83909c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
83919c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
83929c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
83939c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
83949c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
83959c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
83969c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
83979c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
84013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84029c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
84039c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
84049c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
84059c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
84069c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
84079c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
84089c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
84099c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
84169c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
84189c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
84209c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
84229c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
84249c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84269c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84279c1eb0729653219b9da9037e044501a6dce79d10glennrp          "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
84313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
84349c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
84369c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
84389c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
84409c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
84429c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84449c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84459c1eb0729653219b9da9037e044501a6dce79d10glennrp          "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
84493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
84683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
84693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
84753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
84843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
84853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
84863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8488bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
84893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
84993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
85113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
85373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
85403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
85433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
85463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
85513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
85533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
85583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
85603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
8593f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
85953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8597e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
8598e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
86114e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
86124e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
86193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8626f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8628f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-b profiles */
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8665bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
8672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
8674bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    LogPNGChunk((int) logging,mng_bKGD,(size_t) (num_bytes-4L));
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
8697e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
8698e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
8699e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
8701e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
8702e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
8703e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
871735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
873435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
873535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
873735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
873835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
874035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
874135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
874335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
874435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
875935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
876135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
876935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
877135ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
877735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
877835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
8794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
8795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
88183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8826e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
8827f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
8832bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
8839bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
8840bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                LogPNGChunk((int) logging,mng_IDAT,(size_t) len);
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8849e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
8850e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8860e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
8861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
88713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8899e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
8900e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
89113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8914e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
8915e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8918e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
8921bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
900873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9064bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9074bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9077bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9081d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
910473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=MagickFalse;
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=(image_info->type == OptimizeType || image_info->type ==
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      UndefinedType);
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (optimize)
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: TRUE");
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: FALSE");
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9158e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9166e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9168e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9183e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sometimes we get PseudoClass images whose RGB values don't match
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    the colors in the colormap.  This code syncs the RGB values.
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Image
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p;
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p->taint && p->storage_class == PseudoClass)
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(p);
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->adjoin == MagickFalse)
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_BUILD_PALETTE
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (optimize)
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Sometimes we get DirectClass images that have 256 colors or fewer.
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        This code will convert them to PseudoClass and build a colormap.
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class != PseudoClass)
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p->colors <= 256)
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p->colors=0;
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p->matte != MagickFalse)
92289c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) SetImageType(p,PaletteMatteType);
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
92309c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) SetImageType(p,PaletteType);
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
92873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
92933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
92953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
92963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
93990261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
9400d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
9401d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
9402d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
9403d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
9404d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
9405d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
9406d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
94124e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
94394e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
94404e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
9492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
9493bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         LogPNGChunk((int) logging,mng_nEED,(size_t) length);
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
95113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9519e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
9520e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9523e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9526e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
9544e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
9545e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
9546e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
9548e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
9549e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
9550e610a071534e448c46460a5aa39ede33bf56b329glennrp             (PerceptualIntent));
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
95553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
956535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
95733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
95793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
95813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
958235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
958335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
95843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
958535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
958635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
958835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
958935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
959135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
959235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
95993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
96023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
96033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
960835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
961035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
96113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
96163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
961835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
962035ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
96243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
962635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
962735ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
96423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
96593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
96683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
9670bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
96713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
96743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
96753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
96763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
96773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
9680bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
96823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
96833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
96843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
96853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
96873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
96883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
96893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
96953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
96963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
96993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
97053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
97063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
97083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
97093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
97103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
97113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
97143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
97163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
97173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
97193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
9723bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
97273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
97283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
97293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
9730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
97333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
97363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
97463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
97513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
97603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
97613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
97673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
97693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
97703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
97733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
97753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
97763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
97883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
97903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
97913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
97923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
97933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
97943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
97953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
97963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
97973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
97983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
97993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
98003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
98013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
98023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
98033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
98043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
98073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
98123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
98133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
98143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
98173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
98183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
98193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
98214e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
98233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
98293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
98403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
98433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
98493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
98553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
98623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
98723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
98753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
98763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
98773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
98803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
98823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
98863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9887d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
98953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
98993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9900d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9902