png.c revision befe4d21bf21c8f8fb5c8cc01fe60fe4accac47f
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. */
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SORT_PALETTE    /* This works as of 5.4.0. */
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
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2568182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
344bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39035ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
482d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C o m p r e s s C o l o r m a p T r a n s F i r s t                       %
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CompressColormapTransFirst compresses an image colormap removing
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  any duplicate and unused color entries and putting the transparent colors
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  first.  Returns MagickTrue on success, MagickFalse on error.
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CompressColormapTransFirst method is:
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned int CompressColormapTransFirst(Image *image)
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
50698156a3a465a004545e39434c63052b955a74d1cglennrp%      This function updates image->colors and image->colormap.
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType CompressColormapTransFirst(Image *image)
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    remap_needed,
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k;
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j,
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors,
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *colormap;
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const IndexPacket
5255c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top_used;
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
533bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *map,
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *opacity;
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *marker,
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_transparency;
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if colormap can be compressed.
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
55198156a3a465a004545e39434c63052b955a74d1cglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
552e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "    CompressColorMapTransFirst %s (%.20g colors)",image->filename,
553e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) image->colors);
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class != PseudoClass || image->colors > 256 ||
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors < 2)
55698156a3a465a004545e39434c63052b955a74d1cglennrp    {
55798156a3a465a004545e39434c63052b955a74d1cglennrp      if (image->debug != MagickFalse)
55898156a3a465a004545e39434c63052b955a74d1cglennrp        {
55998156a3a465a004545e39434c63052b955a74d1cglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56098156a3a465a004545e39434c63052b955a74d1cglennrp               "    Could not compress colormap");
56198156a3a465a004545e39434c63052b955a74d1cglennrp          if (image->colors > 256 || image->colors == 0)
56298156a3a465a004545e39434c63052b955a74d1cglennrp            return(MagickFalse);
56398156a3a465a004545e39434c63052b955a74d1cglennrp          else
56498156a3a465a004545e39434c63052b955a74d1cglennrp            return(MagickTrue);
56598156a3a465a004545e39434c63052b955a74d1cglennrp        }
56698156a3a465a004545e39434c63052b955a74d1cglennrp    }
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) AcquireQuantumMemory(image->colors,sizeof(*marker));
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (marker == (unsigned char *) NULL)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) AcquireQuantumMemory(image->colors,sizeof(*opacity));
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (opacity == (IndexPacket *) NULL)
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Mark colors that are present.
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  number_colors=(ssize_t) image->colors;
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    marker[i]=MagickFalse;
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    opacity[i]=OpaqueOpacity;
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  top_used=0;
588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5935c6f789db7a30bad01ace12b09ad9cd471339e94cristy    indexes=GetVirtualIndexQueue(image);
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->matte != MagickFalse)
595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5975c6f789db7a30bad01ace12b09ad9cd471339e94cristy        marker[(int) indexes[x]]=MagickTrue;
5985c6f789db7a30bad01ace12b09ad9cd471339e94cristy        opacity[(int) indexes[x]]=GetOpacityPixelComponent(p);
5995c6f789db7a30bad01ace12b09ad9cd471339e94cristy        if (indexes[x] > top_used)
6005c6f789db7a30bad01ace12b09ad9cd471339e94cristy           top_used=indexes[x];
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p++;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6065c6f789db7a30bad01ace12b09ad9cd471339e94cristy        marker[(int) indexes[x]]=MagickTrue;
6075c6f789db7a30bad01ace12b09ad9cd471339e94cristy        if (indexes[x] > top_used)
6085c6f789db7a30bad01ace12b09ad9cd471339e94cristy           top_used=indexes[x];
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Mark background color, topmost occurrence if more than one.
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=number_colors-1; i; i--)
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsColorEqual(image->colormap+i,&image->background_color))
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          marker[i]=MagickTrue;
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Unmark duplicates.
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors-1; i++)
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            marker[j]=MagickFalse;
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Count colors that still remain.
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_transparency=MagickFalse;
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  new_number_colors=0;
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        new_number_colors++;
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (opacity[i] != OpaqueOpacity)
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          have_transparency=MagickTrue;
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!have_transparency || (marker[0] &&
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (opacity[0] == (Quantum) TransparentOpacity)))
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      && (new_number_colors == number_colors))
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        No duplicate or unused entries, and transparency-swap not needed.
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  remap_needed=MagickFalse;
662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((ssize_t) top_used >= new_number_colors)
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     remap_needed=MagickTrue;
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress colormap.
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) AcquireQuantumMemory(image->colors,
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*colormap));
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (colormap == (PixelPacket *) NULL)
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Eliminate unused colormap entries.
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) AcquireQuantumMemory((size_t) number_colors,
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*map));
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (map == (IndexPacket *) NULL)
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  k=0;
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    map[i]=(IndexPacket) k;
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               map[j]=(IndexPacket) k;
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               marker[j]=MagickFalse;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        k++;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=0;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        colormap[j]=image->colormap[i];
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        j++;
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Move the first transparent color to palette entry 0.
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < number_colors; i++)
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PixelPacket
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              temp_colormap;
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            temp_colormap=colormap[0];
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[0]=colormap[(int) map[i]];
732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            colormap[(ssize_t) map[i]]=temp_colormap;
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (j=0; j < number_colors; j++)
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (map[j] == 0)
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=map[i];
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else if (map[j] == map[i])
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=0;
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            remap_needed=MagickTrue;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) RelinquishMagickMemory(marker);
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (remap_needed)
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ExceptionInfo
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *exception;
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register IndexPacket
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *pixels;
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register PixelPacket
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *q;
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Remap pixels.
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=(&image->exception);
764bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=GetAuthenticIndexQueue(image);
770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j=(int) pixels[x];
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels[x]=map[j];
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < new_number_colors; i++)
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i]=colormap[i];
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
782bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->colors=(size_t) new_number_colors;
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) RelinquishMagickMemory(map);
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s G r a y                                                     %
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsGray(Image *image)
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
808bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsGray(image->colormap+i) == MagickFalse)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=(ssize_t) image->columns-1; x >= 0; x--)
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (IsGray(p) == MagickFalse)
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       p++;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s M o n o c h r o m e                                         %
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   and is more accurate.                                                     %
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsMonochrome(Image *image)
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((IsGray(image->colormap+i) == MagickFalse) ||
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((image->colormap[i].red != 0) &&
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (image->colormap[i].red != (Quantum) QuantumRange)))
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
881bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
886bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=(ssize_t) image->columns-1; x >= 0; x--)
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
900d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1012d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1013bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1058e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1059e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1061d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1067d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1181e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1182e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1210bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
1306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1343bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1345bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1353bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1391bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1393bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1394bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1411bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
14148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14238182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
1439faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1441faa852bad40107edae19405e76a299057668d795glennrp#else
1442faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1443faa852bad40107edae19405e76a299057668d795glennrp#endif
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1456cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1498bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
1529f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
1550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
1610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1665faa852bad40107edae19405e76a299057668d795glennrp    pass,
1666faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1667faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1668faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1669faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1670faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1671faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1679faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1680faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1681faa852bad40107edae19405e76a299057668d795glennrp
1682faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1683faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1684faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1685faa852bad40107edae19405e76a299057668d795glennrp
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1696faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1697faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1698faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1699faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1700faa852bad40107edae19405e76a299057668d795glennrp
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
17145c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1726bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1745f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
174825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
175461b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
175561b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
175661b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
175761b4c957269727a0a2526edc2331881da8346100glennrp    {
175861b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
175961b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
176061b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
176161b4c957269727a0a2526edc2331881da8346100glennrp    }
176261b4c957269727a0a2526edc2331881da8346100glennrp#  endif
176361b4c957269727a0a2526edc2331881da8346100glennrp#endif
176461b4c957269727a0a2526edc2331881da8346100glennrp
176561b4c957269727a0a2526edc2331881da8346100glennrp
1766ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
1795faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1802f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
18087b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
18097b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
18107b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
18117b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1817faa852bad40107edae19405e76a299057668d795glennrp
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1851991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1852991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1853991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1867991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1871faa852bad40107edae19405e76a299057668d795glennrp
1872faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1873faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1874faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1875faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1876faa852bad40107edae19405e76a299057668d795glennrp
1877faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1878faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1879faa852bad40107edae19405e76a299057668d795glennrp
1880faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1881faa852bad40107edae19405e76a299057668d795glennrp
1882faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1884faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1885faa852bad40107edae19405e76a299057668d795glennrp        {
1886faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1887faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1888faa852bad40107edae19405e76a299057668d795glennrp        }
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1890faa852bad40107edae19405e76a299057668d795glennrp
1891faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1893faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1897e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1898e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1901faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1904faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1907faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1910faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1911faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rendering_intent=(RenderingIntent)
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->global_srgb_intent+1);
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->rendering_intent=(RenderingIntent) (intent+1);
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Reading PNG sRGB chunk: rendering_intent: %d",intent+1);
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1961faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1962faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1963faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1972faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1973faa852bad40107edae19405e76a299057668d795glennrp    {
1974faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1975faa852bad40107edae19405e76a299057668d795glennrp        {
1976faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1977faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1978faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1979faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1980faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1981faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1982faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1983faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1984faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1985faa852bad40107edae19405e76a299057668d795glennrp        }
1986faa852bad40107edae19405e76a299057668d795glennrp    }
1987faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->rendering_intent)
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2004faa852bad40107edae19405e76a299057668d795glennrp      png_set_sRGB(ping,ping_info,image->rendering_intent-1);
2005faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
2006faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
2007faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
2008faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2011faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2018e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2019e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2023faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2024faa852bad40107edae19405e76a299057668d795glennrp    {
2025faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2026faa852bad40107edae19405e76a299057668d795glennrp        {
2027faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2028faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2029faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2030faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2031faa852bad40107edae19405e76a299057668d795glennrp        }
2032faa852bad40107edae19405e76a299057668d795glennrp    }
2033faa852bad40107edae19405e76a299057668d795glennrp
2034faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
20470881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
20480881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
20490881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2058e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2059e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2062faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2072faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
2078faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2095faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2104faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2105faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2124faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2125faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
2127faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
21352cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2137faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2138faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2139faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21412cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21432cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
21442cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
21452cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21462cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21472cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21482cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
21492cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21502cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21512cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
21522cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
21532cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
21542cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
21552cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
21562cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
21572cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
21582cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
21592cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
21602cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21612cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
21622cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
21632cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
21642cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21652cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21662cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
21672cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21682cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
21692cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
21712cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21722cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
21732cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2175faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2177faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2179faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
21802cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21812cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21822cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2183e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2184e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2185e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2186e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
2194faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
220235ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
220335ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
220435ef824baa82511126ff0072ae30eee0da9c05a3cristy
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2209f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2211faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2212faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2213faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2214faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2215faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2216faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2222faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2227faa852bad40107edae19405e76a299057668d795glennrp          transparent_color.red= (Quantum)(ping_trans_color->red);
2228faa852bad40107edae19405e76a299057668d795glennrp          transparent_color.green= (Quantum) (ping_trans_color->green);
2229faa852bad40107edae19405e76a299057668d795glennrp          transparent_color.blue= (Quantum) (ping_trans_color->blue);
2230faa852bad40107edae19405e76a299057668d795glennrp          transparent_color.opacity= (Quantum) (ping_trans_color->gray);
2231faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
2233faa852bad40107edae19405e76a299057668d795glennrp              if (ping_bit_depth < 8)
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  transparent_color.opacity=(Quantum) (((
2236faa852bad40107edae19405e76a299057668d795glennrp                    ping_trans_color->gray)*255)/max_sample);
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2247faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2252faa852bad40107edae19405e76a299057668d795glennrp
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2254faa852bad40107edae19405e76a299057668d795glennrp
2255faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2256faa852bad40107edae19405e76a299057668d795glennrp
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2263bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2266faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2267faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2276faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2277faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2278faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2279faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2280faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2282befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2283befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2284befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2286befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2287befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2295faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2304bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2318faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2327bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2336bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2339faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
2342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
2355347e40f2829bd04656674c58927cc50cda195475glennrp  if ((image->ping != MagickFalse) || (
2356347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2357347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2361e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2365f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2377faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2379faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2389faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2396f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
24067b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
24077b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
24087b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
24097b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2412ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
2413ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2414ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      depth=(ssize_t) ping_bit_depth;
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2427faa852bad40107edae19405e76a299057668d795glennrp      image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2428faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2429faa852bad40107edae19405e76a299057668d795glennrp          (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2430faa852bad40107edae19405e76a299057668d795glennrp          MagickTrue : MagickFalse;
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2435faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2439abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
2451faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2453bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
2457faa852bad40107edae19405e76a299057668d795glennrp                  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS)) &&
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2467faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB)
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2469faa852bad40107edae19405e76a299057668d795glennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2470bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2500faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (4*image->columns); x != 0; x--)
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2506faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (2*image->columns); x != 0; x--)
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2513faa852bad40107edae19405e76a299057668d795glennrp        if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_GRAY)
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
2516faa852bad40107edae19405e76a299057668d795glennrp        if (ping_color_type == PNG_COLOR_TYPE_GRAY ||
2517faa852bad40107edae19405e76a299057668d795glennrp            ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2523faa852bad40107edae19405e76a299057668d795glennrp        else if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_RGB)
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
2526faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_RGB ||
2527faa852bad40107edae19405e76a299057668d795glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2533faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
2537faa852bad40107edae19405e76a299057668d795glennrp        if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
2540faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
2543faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
2546faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
25537a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
25547a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2555cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2556cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
25577a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25587a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25597a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25637a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2582faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2591faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25985c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2601faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2650faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2663bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2669bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2683faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2692bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2703faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
270746f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
2714faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
273380ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27367a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27377a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2738cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2739cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
27407a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27417a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27427a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
27447a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2752b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2753b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27545c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27555c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2756aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27575c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27585c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27595c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27605c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27615c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2762aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27635c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2767bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2774f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2781faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2791c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2792e805a647adebb9faefcbd7f9a73ca8e91870614acristy#if 1  /* balfour fix */
2793c11cf6a442f3046940608a5743a68cc891deb13eglennrp/* From imagemagick discourse server, 5 Feb 2010 */
2794c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2795c11cf6a442f3046940608a5743a68cc891deb13eglennrp    if (storage_class == PseudoClass)
2796c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2797faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2798c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2799faa852bad40107edae19405e76a299057668d795glennrp         for (x=0; x < ping_num_trans; x++)
2800c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
2801e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            image->colormap[x].opacity =
2802e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp              ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
2803c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2804c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2805faa852bad40107edae19405e76a299057668d795glennrp      else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2806c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
28075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         for (x=0; x < (int) image->colors; x++)
2808c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
2809c11cf6a442f3046940608a5743a68cc891deb13eglennrp            if (image->colormap[x].red == transparent_color.opacity)
2810c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
2811c11cf6a442f3046940608a5743a68cc891deb13eglennrp               image->colormap[x].opacity = (Quantum) TransparentOpacity;
2812c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
2813c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2814c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2815d027259799c88ed5e4f12d21a5366031bfef0904cristy      (void) SyncImage(image);
2816c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2817c11cf6a442f3046940608a5743a68cc891deb13eglennrp   else
2818c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2819c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
2821c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2822c11cf6a442f3046940608a5743a68cc891deb13eglennrp        image->storage_class=storage_class;
2823c11cf6a442f3046940608a5743a68cc891deb13eglennrp        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2824c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (q == (PixelPacket *) NULL)
2825c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
28265c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2827c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
2829c11cf6a442f3046940608a5743a68cc891deb13eglennrp          {
2830c11cf6a442f3046940608a5743a68cc891deb13eglennrp            if (ScaleQuantumToChar(q->red) == transparent_color.red &&
2831c11cf6a442f3046940608a5743a68cc891deb13eglennrp                ScaleQuantumToChar(q->green) == transparent_color.green &&
2832c11cf6a442f3046940608a5743a68cc891deb13eglennrp                ScaleQuantumToChar(q->blue) == transparent_color.blue)
2833c11cf6a442f3046940608a5743a68cc891deb13eglennrp               q->opacity=(Quantum) TransparentOpacity;
2834c11cf6a442f3046940608a5743a68cc891deb13eglennrp            else
2835c11cf6a442f3046940608a5743a68cc891deb13eglennrp              SetOpacityPixelComponent(q,OpaqueOpacity);
2836c11cf6a442f3046940608a5743a68cc891deb13eglennrp            q++;
2837c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
2838c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (SyncAuthenticPixels(image,exception) == MagickFalse)
2839c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
2840c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2841c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2842c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2843c11cf6a442f3046940608a5743a68cc891deb13eglennrp#else /* not balfour */
2844c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2845c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2846bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->storage_class=storage_class;
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
28525c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (storage_class == PseudoClass)
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexPacket
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexpacket;
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2859faa852bad40107edae19405e76a299057668d795glennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2860bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
28625c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2863faa852bad40107edae19405e76a299057668d795glennrp                if (indexpacket < ping_num_trans)
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=ScaleCharToQuantum((unsigned char)
2865bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    (255-ping_trans_alpha[(ssize_t) indexpacket]));
28663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2867ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2870faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
28735c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                q->red=image->colormap[(ssize_t) indexpacket].red;
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=q->red;
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=q->red;
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (q->red == transparent_color.opacity)
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) TransparentOpacity;
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2880ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
2885bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ScaleQuantumToChar(q->red) == transparent_color.red &&
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->green) == transparent_color.green &&
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->blue) == transparent_color.blue)
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               q->opacity=(Quantum) TransparentOpacity;
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2892ce70c17bb6433add2eb069515a4f3105989e0662cristy              SetOpacityPixelComponent(q,OpaqueOpacity);
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2898c11cf6a442f3046940608a5743a68cc891deb13eglennrp#endif /* not balfour */
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->depth > 8)
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->depth=8;
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
295190823213d62b0ba18557e61f1e6892c6fffd6cd4cristy            AcquireAlignedMemory(1,sizeof(MngBuffer));
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
2984faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
2986faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2987faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2988faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2989faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
2990faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
2991faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
2992faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
2993faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
2994faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3024f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
308390823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3186bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3209bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3289e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3290e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3301bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3335f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3337f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
338090823213d62b0ba18557e61f1e6892c6fffd6cd4cristy        color_image_info=(ImageInfo *)AcquireAlignedMemory(1,sizeof(ImageInfo));
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
340090823213d62b0ba18557e61f1e6892c6fffd6cd4cristy              AcquireAlignedMemory(1,sizeof(ImageInfo));
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk to color_image->blob
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy IDAT header and chunk data to alpha_image->blob
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk data to alpha_image->blob
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
35388182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
35488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
35498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
35508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
35518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
35528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
35538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
35548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rendering_intent=(RenderingIntent) (p[0]+1);
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35838182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
35848182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36008182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
36018182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
3679bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3712bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3721bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the JNG image.
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.width=jng_width;
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.height=jng_height;
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.x=mng_info->x_off[mng_info->object_id];
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify JNG signature.
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
384890823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(*mng_info));
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3937bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3954bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
396338ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
396438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
396538ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
3966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    following optimizations:
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  16-bit depth is reduced to 8 if all pixels contain samples whose
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       high byte and low byte are identical.
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Opaque matte channel is removed.
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  If matte channel is present but only one transparent color is
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       present, RGB+tRNS is written instead of RGBA
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       this can be done without loss.
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Palette is sorted to remove unused entries and to put a
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       transparent color first, if PNG_SORT_PALETTE is also defined.
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
402390823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->optimize=image_info->type == OptimizeType;
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Verify MNG signature.
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize some nonzero members of the MngInfo structure.
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4052bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4053bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4099e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4100e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4113bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4152bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
4154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4159e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4161e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
41648182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
41758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
4201e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4202e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4203f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4207bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
42268182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4237e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4239e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) | (p[5] << 16) |
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
4285bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) | (p[9] << 16) |
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[10] << 8) | p[11]);
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4290e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4291f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4293e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4294f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global PLTE.
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
4357bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
436335ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
439212560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4400bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44038182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global cHRM
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
44218182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
44228182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
44248182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
44268182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
44288182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
44308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
44328182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_srgb_intent=(RenderingIntent) (p[0]+1);
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Note the delay and frame clipping boundaries.
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
4489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
4492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45058182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
45068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
45078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
45088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
4509bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4510bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4516e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4520bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4521bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
4522bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4523bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
4524bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4525bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4531e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4540e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Frame_clipping: L=%.20g R=%.20g T=%.20g B=%.20g",
4541e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4542e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
4550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
4552bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4560e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4561e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4600e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4601e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4602e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read DISC or SEEK.
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4661bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4664bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4676bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              read MOVE
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4685bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Record starting point.
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4717e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4718e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4752e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        "  ENDL: LOOP level %.20g has %.20g remaining iterations ",
4753e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4754f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
49368182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
49388182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
4961bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
4963bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
50278182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
50288182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5041bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5043bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Make a background rectangle.
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5082e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5083e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5129e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5130e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5131e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
5180bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-2)*(mng_info->magn_mx);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=image->columns;
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-3)*(mng_info->magn_mx-1);
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-2)*(mng_info->magn_my);
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=image->rows;
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-3)*(mng_info->magn_my-1);
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5325bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
5329bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5365e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5366bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
5381bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5384bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
5385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5387bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5388bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
5396bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5407bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
5413bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
54155c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5434bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5436bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5437bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5439bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5440bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5443bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5446bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5466bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5497e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5499bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
5507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5510bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
5512bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5513bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5516bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5519bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5536bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5539bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5542bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5545bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5568bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5586bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
5589bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
5645bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
5646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* Determine if bit depth can be reduced from 16 to 8.
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * Note that the method GetImageDepth doesn't check background
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * and doesn't handle PseudoClass specially.  Also it uses
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * multiplication and division by 257 instead of shifting, so
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * might be slower.
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->optimize && image->depth == 16)
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ok_to_reduce;
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const PixelPacket
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *p;
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5700bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ok_to_reduce=(((((size_t) image->background_color.red >> 8) &
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     0xff)
5702bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.red & 0xff)) &&
5703bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.green >> 8) & 0xff)
5704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.green & 0xff)) &&
5705bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.blue >> 8) & 0xff)
5706bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.blue & 0xff)));
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce && image->storage_class == PseudoClass)
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int indx;
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5711bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (indx=0; indx < (ssize_t) image->colors; indx++)
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    8) & 0xff)
5715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5719bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].blue & 0xff)));
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == MagickFalse)
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((ok_to_reduce != MagickFalse) &&
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->storage_class != PseudoClass))
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              y;
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5730bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              x;
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5733bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (y=0; y < (ssize_t) image->rows; y++)
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=((
5741bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->red >> 8) & 0xff) ==
5742bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->red & 0xff)) &&
5743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->green >> 8) & 0xff) ==
5744bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->green & 0xff)) &&
5745bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->blue >> 8) & 0xff) ==
5746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->blue & 0xff)) &&
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((!image->matte ||
5748bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->opacity >> 8) & 0xff) ==
5749bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->opacity & 0xff)))));
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == 0)
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (x != 0)
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce)
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->depth=8;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Reducing PNG bit depth to 8 without loss of info");
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
5771bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5889e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
5890e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5901e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5906e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
5968e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
5970f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
5971f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
5972f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5973e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
5974e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
5975f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
5976f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
598425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
599725c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6020bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6023bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
614518b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
614618b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
614718b17443128598500357da7bff2f01683cf32890cristy#endif
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6179514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6180514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
618525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6271bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
6292e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy     (void) printf("writing raw profile: type=%s, length=%.20g\n",
6293e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy       (char *) profile_type, (double) length);
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6313f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
6315bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (LocaleNCompare(name,string,11) == 0) {
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Found %s profile",name);
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=CloneStringInfo(profile);
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data=GetStringInfoDatum(png_profile),
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       length=(png_uint_32) GetStringInfoLength(png_profile);
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[4]=data[3];
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[3]=data[2];
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[2]=data[1];
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[1]=data[0];
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,length-5);  /* data length */
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,length-1,data+1);
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=DestroyStringInfo(png_profile);
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6399cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6400cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6401e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6402e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
64035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     palette;
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
64085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
64095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
64105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
64185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
64195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
64205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6421bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
64315c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
64455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_bit_depth,
64465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
64475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
64485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
64495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
64505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
64515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
64545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
64555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6466f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
64705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=0,
64715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
64725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
64735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
64745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
64755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
64765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
64785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
64795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
64805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
64815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
64825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
64845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
64855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
64865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
64875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6488ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_colors=image->colors;
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=image->depth;
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_matte=image->matte;
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->IsPalette=image->storage_class == PseudoClass &&
6496057310ded72df25c84f1ad647129a95c1f1753e3cristy            image_colors <= 256 && !IsOpaqueImage(image,&image->exception);
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->optimize=image_info->type == OptimizeType;
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6532f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
65495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_width=image->columns;
65505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_height=image->rows;
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6565e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6567e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6569e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6571e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth=%.20g",(double) image->depth);
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6573e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    requested PNG image_depth=%.20g",(double) image->depth);
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
65765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution);
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution);
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_UNKNOWN;
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) image->x_resolution;
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) image->y_resolution;
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up pHYs chunk");
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x || image->page.y)
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (png_int_32) image->page.y, 0);
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up oFFs chunk");
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_color_16
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        background;
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_depth < MAGICKCORE_QUANTUM_DEPTH)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6629bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             maxval;
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          maxval=(1UL << image_depth)-1;
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=(png_uint_16)
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.red));
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=(png_uint_16)
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.green));
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=(png_uint_16)
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.blue));
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=(png_uint_16)
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*PixelIntensity(&image->background_color)));
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=image->background_color.red;
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=image->background_color.green;
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=image->background_color.blue;
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_16) PixelIntensity(&image->background_color);
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      background.index=(png_byte) background.gray;
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Setting up bKGd chunk");
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_bKGD(ping,ping_info,&background);
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
66645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_bit_depth=8;
66655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: make this a function cause it's used twice, except
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             for reducing the sample depth from 8. */
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          QuantizeInfo
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantize_info;
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6673bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             number_colors,
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             save_number_colors;
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image->storage_class == DirectClass) || (number_colors > 256))
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GetQuantizeInfo(&quantize_info);
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MagickFalse ? MagickTrue : MagickFalse;
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                256UL);
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) QuantizeImage(&quantize_info,image);
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors=image_colors;
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) SyncImage(image);
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6690e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    Colors quantized to %.20g",(double) number_colors);
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
66935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Set image palette.
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
66975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          save_number_colors=image_colors;
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (CompressColormapTransFirst(image) == MagickFalse)
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
670298156a3a465a004545e39434c63052b955a74d1cglennrp          number_colors=image->colors;
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=save_number_colors;
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_color *) AcquireQuantumMemory(257,
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*palette));
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (palette == (png_color *) NULL)
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
671198156a3a465a004545e39434c63052b955a74d1cglennrp                "  Setting up PLTE chunk with %d colors",
671298156a3a465a004545e39434c63052b955a74d1cglennrp                (int) number_colors);
6713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) number_colors; i++)
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %3ld (%3d,%3d,%3d)",
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %5ld (%5d,%5d,%5d)",
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6725f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                (long) i,palette[i].red,palette[i].green,palette[i].blue);
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors++;
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_colorp) RelinquishMagickMemory(palette);
67375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            image_depth=ping_bit_depth;
67385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              int
67455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                trans_alpha[256];
67465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
6751bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
67525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 trans_alpha[i]=255;
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
6754bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register const PixelPacket
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *p;
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetAuthenticPixels(image,0,y,image->columns,1,exception);
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (PixelPacket *) NULL)
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
67625c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexes=GetAuthenticIndexQueue(image);
6763bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
67675c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      indexes[x]=(IndexPacket) (number_colors-1);
6768bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans_alpha[(ssize_t) indexes[x]]=(png_byte) (255-
6769ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (SyncAuthenticPixels(image,exception) == MagickFalse)
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
6776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
67775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if (trans_alpha[i] != 255)
67785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=(unsigned short) (i+1);
67795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
67815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 png_set_invalid(ping, ping_info, PNG_INFO_tRNS);
67825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping, ping_info, PNG_INFO_tRNS))
67835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
67845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
67855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                {
67865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  for (i=0; i<256; i++)
67875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                     ping_trans_alpha[i]=(png_byte) trans_alpha[i];
67885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                }
67895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (void) png_set_tRNS(ping, ping_info,
67915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  ping_trans_alpha,
67925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  ping_num_trans,
67935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  &ping_trans_color);
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Identify which colormap entry is the background color.
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
6798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
67995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (IsPNGColorEqual(ping_background,image->colormap[i]))
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
68015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_background.index=(png_byte) i;
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
68115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
68165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
68245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
68255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "Selecting PNG colortype");
68335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) ((matte == MagickTrue)?
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         "Selected PNG colortype=%d",ping_color_type);
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
68685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
68695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB ||
68705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
68715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=8;
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
68815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (ping_bit_depth < (int)mng_info->write_png_depth)
68825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth = mng_info->write_png_depth;
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
688835ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
68895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
689035ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
68915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6896e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "    Number of colors: %.20g",(double) image_colors);
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                "    Tentative PNG bit depth: %d",ping_bit_depth);
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
69025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               old_bit_depth=ping_bit_depth;
69035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               if (ping_bit_depth < (int)mng_info->write_png_depth)
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
69055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth = mng_info->write_png_depth;
69065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth > 8)
69075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth = 8;
69085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth != (int) old_bit_depth)
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6912e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                           "    Colors increased to %.20g",(double)
6913f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                           image_colors);
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6923e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6925e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6927e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6929e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (matte && (mng_info->optimize || mng_info->IsPalette))
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
69385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
6939bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6944bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6962bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (x != 0)
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6971bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((y == (ssize_t) image->rows) && (x == (ssize_t) image->columns))
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
69745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
69775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type&=0x03;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
69855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 8)
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
69875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 4)
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
69895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 2)
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
69915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 1)
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
69935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.red=(png_uint_16)
6994ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetRedPixelComponent(p)) & mask);
69955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.green=(png_uint_16)
6996ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetGreenPixelComponent(p)) & mask);
69975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.blue=(png_uint_16)
6998ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetBluePixelComponent(p)) & mask);
69995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.gray=(png_uint_16)
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
70015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.index=(png_byte)
700246f08209f719f4adeea742c45873c2714e80cdb9cristy            (ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))));
70035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (void) png_set_tRNS(ping, ping_info, NULL, 0,
70045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             &ping_trans_color);
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
7012bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7019bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p) == 0)
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for multiple
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent colors.  */
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                semitransparency. */
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               else
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p))
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (x != 0)
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (x != 0)
70475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
70555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
70565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
70575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
70625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((mng_info->optimize || mng_info->IsPalette) &&
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
706835ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
70709c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
70755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray*=0x0101;
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
708035ef824baa82511126ff0072ae30eee0da9c05a3cristy          image_colors=one << image_depth;
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
70825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
70865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
70905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
709135ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7092bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
70935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (mng_info->optimize && ping_color_type ==
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7107bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
71229c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
71249c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
71269c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
71295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7134bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
713517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
713617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
713717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
713817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
71445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71479c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
71489c1eb0729653219b9da9037e044501a6dce79d10glennrp                if (logging)
71499c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71509c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
7155bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   save_number_colors;
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->optimize)
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    save_number_colors=image_colors;
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (CompressColormapTransFirst(image) == MagickFalse)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       ThrowWriterException(ResourceLimitError,
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                            "MemoryAllocationFailed");
716498156a3a465a004545e39434c63052b955a74d1cglennrp                    number_colors=image->colors;
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image_colors=save_number_colors;
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_color *) AcquireQuantumMemory(257,
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sizeof(*palette));
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (palette == (png_color *) NULL)
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
7173bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging)
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
718198156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
718298156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_colorp) RelinquishMagickMemory(palette);
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7189befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
7190befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
7191befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
71925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
7193befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
7194befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
71955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const PixelPacket
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p;
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[256];
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const IndexPacket
72105c6f789db7a30bad01ace12b09ad9cd471339e94cristy                *packet_indexes;
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
7216bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[i]=256;
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
7219bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (const PixelPacket *) NULL)
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
72245c6f789db7a30bad01ace12b09ad9cd471339e94cristy                packet_indexes=GetVirtualIndexQueue(image);
7225bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      IndexPacket
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        packet_index;
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72325c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      packet_index=packet_indexes[x];
7233bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      assert((size_t) packet_index < number_colors);
7234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      if (trans[(ssize_t) packet_index] != 256)
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
7236bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                          if (trans[(ssize_t) packet_index] != (png_byte) (255-
7237ce70c17bb6433add2eb069515a4f3105989e0662cristy                             ScaleQuantumToChar(GetOpacityPixelComponent(p))))
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
72395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                              ping_color_type=(png_byte)
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                PNG_COLOR_TYPE_RGB_ALPHA;
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              break;
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
7244bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans[(ssize_t) packet_index]=(png_byte) (255-
7245ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
72515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=0;
72525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
72535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_PLTE);
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->IsPalette=MagickFalse;
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) SyncImage(image);
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (logging)
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "    Cannot write image as indexed PNG, writing RGBA.");
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7264bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] == 256)
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    trans[i]=255;
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] != 255)
72695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_num_trans=(unsigned short) (i+1);
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
72735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
72745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
72755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
72765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
72779c1eb0729653219b9da9037e044501a6dce79d10glennrp                {
72789c1eb0729653219b9da9037e044501a6dce79d10glennrp                  for (i=0; i < (ssize_t) number_colors; i++)
72799c1eb0729653219b9da9037e044501a6dce79d10glennrp                      ping_trans_alpha[i]=(png_byte) trans[i];
72809c1eb0729653219b9da9037e044501a6dce79d10glennrp                }
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
72915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
72925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
72935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
72945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
73015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_color_16
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           background;
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
731035ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
731135ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
731235ef824baa82511126ff0072ae30eee0da9c05a3cristy
731322ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         background.gray=(png_uint_16)
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Setting up bKGD chunk");
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_set_bKGD(ping,ping_info,&background);
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
73255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
732717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
732817a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
732917a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
733017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
733117a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
733217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
733317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7334bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
733517a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
733617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
733717a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
733817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7339bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
734017a1485544c62993fc7a94e343c87fed5f3e6407glennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
734117a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
734217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
734317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
734417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
734517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        if (logging)
734617a1485544c62993fc7a94e343c87fed5f3e6407glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
734717a1485544c62993fc7a94e343c87fed5f3e6407glennrp            "  Setting up bKGD chunk with index=%d",(int) i);
734817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
734917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        png_set_bKGD(ping,ping_info,&ping_background);
735017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
735117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up deflate compression");
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression buffer size: 32768");
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
74005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter=PNG_ALL_FILTERS;
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((quality % 10) != 5)
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
74175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
74185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_NO_FILTERS;
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_ALL_FILTERS;
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
74683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_set_sRGB(ping,ping_info,(int) (image->rendering_intent-1));
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
75245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
75255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
75265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
75315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
75355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
75375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
7538991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
75395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
75485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
75555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_error(ping,
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && !image->matte)
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
7567b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
7568b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7569b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7572e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  if (image->matte == MagickTrue && ping_color_type < 4)
7573e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
7574e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp      if (ping_color_type == 3 && ping_num_trans == 0)
7575e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp        {
7576e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
7577e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp          if (logging != MagickFalse)
7578e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7579e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp              "  Ignoring request to write tRNS chunk with num_trans==0");
7580e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp        }
7581e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp      else
7582e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp        (void) png_set_tRNS(ping, ping_info,
7583e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp                            ping_trans_alpha,
7584e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp                            ping_num_trans,
7585e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp                            &ping_trans_color);
7586e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
7587e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75925af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
75935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
75945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
75955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
75965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76069c1eb0729653219b9da9037e044501a6dce79d10glennrp      unsigned char
76079c1eb0729653219b9da9037e044501a6dce79d10glennrp        chunk[14];
76089c1eb0729653219b9da9037e044501a6dce79d10glennrp
76099c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
76109c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGType(chunk,mng_vpAg);
76119c1eb0729653219b9da9037e044501a6dce79d10glennrp      LogPNGChunk((int) logging,mng_vpAg,9L);
76129c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+4,(png_uint_32) image->page.width);
76139c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+8,(png_uint_32) image->page.height);
76149c1eb0729653219b9da9037e044501a6dce79d10glennrp      chunk[12]=0;   /* unit = pixels */
76159c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlob(image,13,chunk);
76169c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
76209c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
76229c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
7631b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
7632b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
76337202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7635b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
7637b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7638b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
7639b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
7640b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7641b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
7643b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7644b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
7645b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7647b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (logging)
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7649b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7650b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
7651b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7652e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
76615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7676f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7680ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
7681ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
7682ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mng_info->optimize || mng_info->IsPalette ||
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
7701bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
7715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
7726bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
7729b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7730b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7731b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
77515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7754bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
77595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
7767b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7768b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7769b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                     "    Writing GRAY PNG pixels (2)");
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7773b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7774b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7775b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (2)");
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7779b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7780b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7781b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (2)");
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
77933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
77953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
77963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
7797bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
77983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
78003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
78013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
78115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7812b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
7813b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
7814b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
7815b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                if (logging && y == 0)
7816b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7817b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (3)");
7818b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
78193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
78223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
7825b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            if (logging && y == 0)
7826b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7827b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "    Writing row of pixels (3)");
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
78313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
78365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging)
78393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7844bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7846e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            if (logging && y == 0)
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
78555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7856b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
785707cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp                if (logging && y == 0)
7858b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7859b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "  Writing GRAY_ALPHA PNG pixels (4)");
7860b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
7861b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
7862b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
78643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
786607cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp            if (logging && y == 0)
7867b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7868b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "  Writing row of pixels (4)");
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7880b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
7881b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7886b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7888e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
78893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7890e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
78913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
78923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
79173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
79223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
79515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
79525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
79653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
79735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
79753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
79765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
79883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  s[0]=(char) ping_bit_depth;
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
80063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8008f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
80153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
80263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
80303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
80313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
80353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
80373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
80433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
80453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
80473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
80503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
80553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
80583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
80613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
80673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               channel is present even if the image is fully opaque.
80683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               from the application programming interfaces.
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
80773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
80853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
81003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Allow all other PNG subformats to be requested via new
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "-define png:bit-depth -define png:color-type" options.
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  subsequent profiles from overwriting the preceding ones:
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
816190823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81799c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
81809c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
81819c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0 /* this does not work */
81839c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
81849c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,PaletteMatteType);
81859c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
81869c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,PaletteType);
81879c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81939c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
81949c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
81959c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
81969c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
81979c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
81989c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
81999c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
82009c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82059c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
82069c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
82079c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
82089c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
82099c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
82109c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
82119c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
82129c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
82199c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
82219c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
82239c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
82243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
82259c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
82279c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82299c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82309c1eb0729653219b9da9037e044501a6dce79d10glennrp          "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
82379c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
82399c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
82419c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
82439c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
82459c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82479c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82489c1eb0729653219b9da9037e044501a6dce79d10glennrp          "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
83023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
83133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
83153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
83213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
83613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
83903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
8396f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8400e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
8401e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+4,image->columns);
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+8,image->rows);
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8429f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8431f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
84363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
84483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-b profiles */
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
84523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
84543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
84693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
8475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
8477bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    LogPNGChunk((int) logging,mng_bKGD,(size_t) (num_bytes-4L));
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
84813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
84843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
84853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
84863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
84883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
84893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
84993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (image->rendering_intent-1);
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (PerceptualIntent-1);
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
85113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
851635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
853335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
853435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
853635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
853735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
853935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
854035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
854235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
854335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
85463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
85513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
85533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
85543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
855835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
856035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
856835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
857035ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
857635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
857735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
85863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
8593bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
8594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
85953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8619bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8625e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
8626f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
8631bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
8638bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
8639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                LogPNGChunk((int) logging,mng_IDAT,(size_t) len);
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8648e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
8649e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8659e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
8660bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8698e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
8699e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8713e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
8714e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8717e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
8720bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
87713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
880790823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
88183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
88493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8863bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
88713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8873bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8880d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
890390823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
89113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
89183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=MagickFalse;
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=(image_info->type == OptimizeType || image_info->type ==
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      UndefinedType);
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (optimize)
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: TRUE");
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: FALSE");
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8957e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8965e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8967e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8982e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sometimes we get PseudoClass images whose RGB values don't match
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    the colors in the colormap.  This code syncs the RGB values.
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Image
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p;
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p->taint && p->storage_class == PseudoClass)
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(p);
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->adjoin == MagickFalse)
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_BUILD_PALETTE
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (optimize)
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Sometimes we get DirectClass images that have 256 colors or fewer.
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        This code will convert them to PseudoClass and build a colormap.
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class != PseudoClass)
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p->colors <= 256)
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p->colors=0;
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p->matte != MagickFalse)
90279c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) SetImageType(p,PaletteMatteType);
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
90299c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) SetImageType(p,PaletteType);
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 final_delay=10;
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 (void) ThrowMagickException(&image->exception,
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "input has zero delay between all frames; assuming 10 cs",
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "`%s'","");
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1UL*image->ticks_per_second/final_delay;
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+4,mng_info->page.width);
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+8,mng_info->page.height);
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
92873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
9288bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
9289bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         LogPNGChunk((int) logging,mng_nEED,(size_t) length);
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
92933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
92953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
92963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9315e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
9316e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9319e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9322e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (image->rendering_intent-1);
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (PerceptualIntent-1);
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
935735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
937435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
937535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
937735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
937835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
938035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
938135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
938335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
938435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
940035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
940235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
941035ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
941235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
941835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
941935ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
9462bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
9472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
95113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
9515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
95193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
95203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
9522bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
95233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
95263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9540bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
95553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
95653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
95793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
95813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
95823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
95833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
95843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
95863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
95883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
95893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
95913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
95923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
95993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
96023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
96033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
96103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
96113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->delay=image->delay;
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
96163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
96363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
96593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
96683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
96713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
96733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
96743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
96753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
96763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
96773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9679d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
96823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
96833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
96843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
96853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
96873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
96883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
96893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9692d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9694