png.c revision 73bd4a51b419e914565bdf204bf1540dc4c8ee26
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
24505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrptypedef struct _UShortPixelPacket
24605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp{
24705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  unsigned short
24805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    red,
24905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    green,
25005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    blue,
25105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    opacity,
25205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp    index;
25305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp} UShortPixelPacket;
25405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2668182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
354bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40035ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
432bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
479e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
480e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_from_Magick_RenderingIntent(const RenderingIntent intent)
481e610a071534e448c46460a5aa39ede33bf56b329glennrp{
482e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
483e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
484e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
485e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
486e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
487e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
488e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
489e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
490e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
491e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
492e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
493e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
494e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
495e610a071534e448c46460a5aa39ede33bf56b329glennrp}
496e610a071534e448c46460a5aa39ede33bf56b329glennrp
497e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
498e610a071534e448c46460a5aa39ede33bf56b329glennrpPNG_RenderingIntent_to_Magick_RenderingIntent(const int png_intent)
499e610a071534e448c46460a5aa39ede33bf56b329glennrp{
500e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (png_intent)
501e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
502e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
503e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
504e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
505e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
506e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
507e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
508e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
509e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
510e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
511e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
512e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
513e610a071534e448c46460a5aa39ede33bf56b329glennrp}
514e610a071534e448c46460a5aa39ede33bf56b329glennrp
515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
528d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   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                       %
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CompressColormapTransFirst compresses an image colormap removing
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  any duplicate and unused color entries and putting the transparent colors
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  first.  Returns MagickTrue on success, MagickFalse on error.
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CompressColormapTransFirst method is:
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned int CompressColormapTransFirst(Image *image)
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
55298156a3a465a004545e39434c63052b955a74d1cglennrp%      This function updates image->colors and image->colormap.
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType CompressColormapTransFirst(Image *image)
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    remap_needed,
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k;
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j,
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors,
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *colormap;
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const IndexPacket
5715c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top_used;
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *map,
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *opacity;
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *marker,
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_transparency;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if colormap can be compressed.
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
59798156a3a465a004545e39434c63052b955a74d1cglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
598e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "    CompressColorMapTransFirst %s (%.20g colors)",image->filename,
599e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) image->colors);
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class != PseudoClass || image->colors > 256 ||
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors < 2)
60298156a3a465a004545e39434c63052b955a74d1cglennrp    {
60398156a3a465a004545e39434c63052b955a74d1cglennrp      if (image->debug != MagickFalse)
60498156a3a465a004545e39434c63052b955a74d1cglennrp        {
60598156a3a465a004545e39434c63052b955a74d1cglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60698156a3a465a004545e39434c63052b955a74d1cglennrp               "    Could not compress colormap");
60798156a3a465a004545e39434c63052b955a74d1cglennrp          if (image->colors > 256 || image->colors == 0)
60898156a3a465a004545e39434c63052b955a74d1cglennrp            return(MagickFalse);
60998156a3a465a004545e39434c63052b955a74d1cglennrp          else
61098156a3a465a004545e39434c63052b955a74d1cglennrp            return(MagickTrue);
61198156a3a465a004545e39434c63052b955a74d1cglennrp        }
61298156a3a465a004545e39434c63052b955a74d1cglennrp    }
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) AcquireQuantumMemory(image->colors,sizeof(*marker));
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (marker == (unsigned char *) NULL)
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) AcquireQuantumMemory(image->colors,sizeof(*opacity));
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (opacity == (IndexPacket *) NULL)
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Mark colors that are present.
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
627bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  number_colors=(ssize_t) image->colors;
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    marker[i]=MagickFalse;
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    opacity[i]=OpaqueOpacity;
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  top_used=0;
634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6395c6f789db7a30bad01ace12b09ad9cd471339e94cristy    indexes=GetVirtualIndexQueue(image);
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->matte != MagickFalse)
641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6435c6f789db7a30bad01ace12b09ad9cd471339e94cristy        marker[(int) indexes[x]]=MagickTrue;
6445c6f789db7a30bad01ace12b09ad9cd471339e94cristy        opacity[(int) indexes[x]]=GetOpacityPixelComponent(p);
6455c6f789db7a30bad01ace12b09ad9cd471339e94cristy        if (indexes[x] > top_used)
6465c6f789db7a30bad01ace12b09ad9cd471339e94cristy           top_used=indexes[x];
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p++;
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
650bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6525c6f789db7a30bad01ace12b09ad9cd471339e94cristy        marker[(int) indexes[x]]=MagickTrue;
6535c6f789db7a30bad01ace12b09ad9cd471339e94cristy        if (indexes[x] > top_used)
6545c6f789db7a30bad01ace12b09ad9cd471339e94cristy           top_used=indexes[x];
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Mark background color, topmost occurrence if more than one.
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=number_colors-1; i; i--)
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsColorEqual(image->colormap+i,&image->background_color))
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          marker[i]=MagickTrue;
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Unmark duplicates.
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors-1; i++)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            marker[j]=MagickFalse;
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Count colors that still remain.
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_transparency=MagickFalse;
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  new_number_colors=0;
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        new_number_colors++;
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (opacity[i] != OpaqueOpacity)
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          have_transparency=MagickTrue;
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!have_transparency || (marker[0] &&
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (opacity[0] == (Quantum) TransparentOpacity)))
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      && (new_number_colors == number_colors))
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        No duplicate or unused entries, and transparency-swap not needed.
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  remap_needed=MagickFalse;
708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((ssize_t) top_used >= new_number_colors)
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     remap_needed=MagickTrue;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress colormap.
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) AcquireQuantumMemory(image->colors,
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*colormap));
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (colormap == (PixelPacket *) NULL)
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Eliminate unused colormap entries.
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) AcquireQuantumMemory((size_t) number_colors,
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*map));
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (map == (IndexPacket *) NULL)
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  k=0;
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    map[i]=(IndexPacket) k;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               map[j]=(IndexPacket) k;
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               marker[j]=MagickFalse;
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        k++;
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=0;
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        colormap[j]=image->colormap[i];
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        j++;
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Move the first transparent color to palette entry 0.
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < number_colors; i++)
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PixelPacket
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              temp_colormap;
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            temp_colormap=colormap[0];
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[0]=colormap[(int) map[i]];
778bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            colormap[(ssize_t) map[i]]=temp_colormap;
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (j=0; j < number_colors; j++)
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (map[j] == 0)
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=map[i];
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else if (map[j] == map[i])
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=0;
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            remap_needed=MagickTrue;
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) RelinquishMagickMemory(marker);
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (remap_needed)
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ExceptionInfo
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *exception;
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register IndexPacket
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *pixels;
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register PixelPacket
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *q;
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Remap pixels.
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=(&image->exception);
810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=GetAuthenticIndexQueue(image);
816bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j=(int) pixels[x];
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels[x]=map[j];
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < new_number_colors; i++)
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i]=colormap[i];
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
828bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->colors=(size_t) new_number_colors;
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) RelinquishMagickMemory(map);
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s G r a y                                                     %
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsGray(Image *image)
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
854bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
866bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsGray(image->colormap+i) == MagickFalse)
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
876bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=(ssize_t) image->columns-1; x >= 0; x--)
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (IsGray(p) == MagickFalse)
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       p++;
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s M o n o c h r o m e                                         %
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   and is more accurate.                                                     %
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsMonochrome(Image *image)
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
907bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
918bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((IsGray(image->colormap+i) == MagickFalse) ||
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((image->colormap[i].red != 0) &&
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (image->colormap[i].red != (Quantum) QuantumRange)))
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
927bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=(ssize_t) image->columns-1; x >= 0; x--)
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
946d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1058d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1059bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1104e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1105e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1107d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1113d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1227e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1228e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1256bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1329bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1343bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
1352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1391bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1399bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1437bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1438bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1439bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1440bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14598182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
14608182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14698182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14718182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
1485faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1487faa852bad40107edae19405e76a299057668d795glennrp#else
1488faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1489faa852bad40107edae19405e76a299057668d795glennrp#endif
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1502cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
1575f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
1596bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
1656bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1711faa852bad40107edae19405e76a299057668d795glennrp    pass,
1712faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1713faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1714faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1715faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1716faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1717faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
172205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp  UShortPixelPacket
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1725faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1726faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1727faa852bad40107edae19405e76a299057668d795glennrp
1728faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1729faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1730faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1731faa852bad40107edae19405e76a299057668d795glennrp
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1742faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1743faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1744faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1745faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1746faa852bad40107edae19405e76a299057668d795glennrp
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
17605c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1762bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1772bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1791f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
179425c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
180061b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
180161b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
180261b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
180361b4c957269727a0a2526edc2331881da8346100glennrp    {
180461b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
180561b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
180661b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
180761b4c957269727a0a2526edc2331881da8346100glennrp    }
180861b4c957269727a0a2526edc2331881da8346100glennrp#  endif
180961b4c957269727a0a2526edc2331881da8346100glennrp#endif
181061b4c957269727a0a2526edc2331881da8346100glennrp
181161b4c957269727a0a2526edc2331881da8346100glennrp
1812ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
1841faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1848f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
18547b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
18557b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
18567b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
18577b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1863faa852bad40107edae19405e76a299057668d795glennrp
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1897991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1898991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1899991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1913991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1917faa852bad40107edae19405e76a299057668d795glennrp
1918faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1919faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1920faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1921faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1922faa852bad40107edae19405e76a299057668d795glennrp
1923faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1924faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1925faa852bad40107edae19405e76a299057668d795glennrp
1926faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1927faa852bad40107edae19405e76a299057668d795glennrp
1928faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1930faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1931faa852bad40107edae19405e76a299057668d795glennrp        {
1932faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1933faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1934faa852bad40107edae19405e76a299057668d795glennrp        }
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1936faa852bad40107edae19405e76a299057668d795glennrp
1937faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1939faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1943e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1944e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1947faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1950faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1953faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1956faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1957faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1992e610a071534e448c46460a5aa39ede33bf56b329glennrp      image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1993e610a071534e448c46460a5aa39ede33bf56b329glennrp        mng_info->global_srgb_intent);
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1996e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent=PNG_RenderingIntent_to_Magick_RenderingIntent(
1997e610a071534e448c46460a5aa39ede33bf56b329glennrp          intent);
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2000e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2008faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2009faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2010faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2019faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2020faa852bad40107edae19405e76a299057668d795glennrp    {
2021faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2022faa852bad40107edae19405e76a299057668d795glennrp        {
2023faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2024faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2025faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2026faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2027faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2028faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2029faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2030faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2031faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2032faa852bad40107edae19405e76a299057668d795glennrp        }
2033faa852bad40107edae19405e76a299057668d795glennrp    }
2034faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2049e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2051e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
2052e610a071534e448c46460a5aa39ede33bf56b329glennrp         PNG_RenderingIntent_from_Magick_RenderingIntent(
2053e610a071534e448c46460a5aa39ede33bf56b329glennrp         image->rendering_intent));
2054faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
2055faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
2056faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
2057faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2060faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2067e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2068e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2072faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2073faa852bad40107edae19405e76a299057668d795glennrp    {
2074faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2075faa852bad40107edae19405e76a299057668d795glennrp        {
2076faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2077faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2078faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2079faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2080faa852bad40107edae19405e76a299057668d795glennrp        }
2081faa852bad40107edae19405e76a299057668d795glennrp    }
2082faa852bad40107edae19405e76a299057668d795glennrp
2083faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
20960881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
20970881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
20980881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2107e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2108e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2111faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2121faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
2127faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2144faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2153faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2154faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
2173faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2174faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
2176faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
21842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      if (ping_bit_depth == MAGICKCORE_QUANTUM_DEPTH)
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2186faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.red=ping_background->red;
2187faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.green=ping_background->green;
2188faa852bad40107edae19405e76a299057668d795glennrp          image->background_color.blue=ping_background->blue;
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21902cbb4489df0a2a31907769956f217d4b9d982bd0glennrp      else /* Scale background components to 16-bit */
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          unsigned int
21932cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            bkgd_scale;
21942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
21952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
21962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21972cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    raw ping_background=(%d,%d,%d).",ping_background->red,
21982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
21992cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
22002cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          bkgd_scale = 1;
22012cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth == 1)
22022cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 255;
22032cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 2)
22042cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 85;
22052cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          else if (ping_bit_depth == 4)
22062cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale = 17;
22072cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (ping_bit_depth <= 8)
22082cbb4489df0a2a31907769956f217d4b9d982bd0glennrp             bkgd_scale *= 257;
22092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
22102cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->red *= bkgd_scale;
22112cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->green *= bkgd_scale;
22122cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          ping_background->blue *= bkgd_scale;
22132cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
22142cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
22152cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            {
22162cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22172cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
22182cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22192cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
22202cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
22212cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            }
22222cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
2224faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
2226faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
2228faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->blue);
2229f17da7472c6195cfc91626d98d166cae04345d34cristy          image->background_color.opacity=OpaqueOpacity;
22302cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
22312cbb4489df0a2a31907769956f217d4b9d982bd0glennrp          if (logging != MagickFalse)
22322cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2233e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "    image->background_color=(%.20g,%.20g,%.20g).",
2234e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.red,
2235e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.green,
2236e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) image->background_color.blue);
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
2244faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
225235ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
225335ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
225435ef824baa82511126ff0072ae30eee0da9c05a3cristy
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2259f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2261faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2262faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2263faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2264faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2265faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2266faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2272faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
227705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.red= (unsigned short)(ping_trans_color->red);
227805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.green= (unsigned short) (ping_trans_color->green);
227905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.blue= (unsigned short) (ping_trans_color->blue);
228005eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp          transparent_color.opacity= (unsigned short) (ping_trans_color->gray);
228105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2282faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
22840f111984738842d27d04aed2a3f823d82a943506glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22850f111984738842d27d04aed2a3f823d82a943506glennrp              if (ping_bit_depth < MAGICKCORE_QUANTUM_DEPTH)
22860f111984738842d27d04aed2a3f823d82a943506glennrp#endif
228705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              transparent_color.opacity=(unsigned short) (
22880f111984738842d27d04aed2a3f823d82a943506glennrp                  ping_trans_color->gray *
228905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                  (65535L/((1UL << ping_bit_depth)-1)));
22900f111984738842d27d04aed2a3f823d82a943506glennrp
229105eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
229205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp              else
229305eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity=(unsigned short) (
229405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                    (ping_trans_color->gray * 65535L)/
229505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                   ((1UL << ping_bit_depth)-1));
22960f111984738842d27d04aed2a3f823d82a943506glennrp#endif
22970f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
22980f111984738842d27d04aed2a3f823d82a943506glennrp              {
22990f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23000f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
23010f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23020f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
23030f111984738842d27d04aed2a3f823d82a943506glennrp              }
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2313faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2318faa852bad40107edae19405e76a299057668d795glennrp
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2320faa852bad40107edae19405e76a299057668d795glennrp
2321faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2322faa852bad40107edae19405e76a299057668d795glennrp
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2327bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2329bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2332faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2333faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2342faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2343faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2344faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2345faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2346faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2348befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2349befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2350befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2352befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2353befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2361faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2370bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2384faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2393bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2402bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2405faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
2408bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
24210ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2422347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2423347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2427e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2431f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2443faa852bad40107edae19405e76a299057668d795glennrp      ping_rowbytes*sizeof(*png_pixels));
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2445faa852bad40107edae19405e76a299057668d795glennrp    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2455faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2462f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
24727b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
24737b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
24747b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
24757b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2478ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
2479ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2480ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2491bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      depth=(ssize_t) ping_bit_depth;
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2493faa852bad40107edae19405e76a299057668d795glennrp      image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2494faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2495faa852bad40107edae19405e76a299057668d795glennrp          (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2496faa852bad40107edae19405e76a299057668d795glennrp          MagickTrue : MagickFalse;
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2498bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2501faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2505abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
2517faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2519bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
2523faa852bad40107edae19405e76a299057668d795glennrp                  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS)) &&
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2533faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB)
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2535faa852bad40107edae19405e76a299057668d795glennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
2536bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
2555bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) image->columns-1; x >= 0; x--)
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2566faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
2567bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (4*image->columns); x != 0; x--)
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2572faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (2*image->columns); x != 0; x--)
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2579faa852bad40107edae19405e76a299057668d795glennrp        if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_GRAY)
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
2582faa852bad40107edae19405e76a299057668d795glennrp        if (ping_color_type == PNG_COLOR_TYPE_GRAY ||
2583faa852bad40107edae19405e76a299057668d795glennrp            ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2589faa852bad40107edae19405e76a299057668d795glennrp        else if (depth == 8 && ping_color_type == PNG_COLOR_TYPE_RGB)
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
2592faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_RGB ||
2593faa852bad40107edae19405e76a299057668d795glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2599faa852bad40107edae19405e76a299057668d795glennrp        else if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
2603faa852bad40107edae19405e76a299057668d795glennrp        if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
2606faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
2609faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
2612faa852bad40107edae19405e76a299057668d795glennrp        else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26197a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
26207a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2621cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2622cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
26237a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
26247a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
26257a287bfadeadea12e47c2376ca78a5d101687142cristy          }
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
26297a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2648faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2657faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26645c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2667faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2674bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2682bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2689bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2698bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2705bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2716faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2717bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2738bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2749faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2758bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2769faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
277346f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
2780faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
279980ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
28027a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
28037a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2804cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2805cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
28067a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
28077a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
28087a287bfadeadea12e47c2376ca78a5d101687142cristy          }
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
28107a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2818b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2819b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
28205c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
28215c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2822aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
28235c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
28245c6f789db7a30bad01ace12b09ad9cd471339e94cristy
28255c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
28265c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
28275c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2828aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
28295c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2840f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2847faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2857c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2858e805a647adebb9faefcbd7f9a73ca8e91870614acristy#if 1  /* balfour fix */
2859c11cf6a442f3046940608a5743a68cc891deb13eglennrp/* From imagemagick discourse server, 5 Feb 2010 */
2860c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2861c11cf6a442f3046940608a5743a68cc891deb13eglennrp    if (storage_class == PseudoClass)
2862c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2863faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2864c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2865faa852bad40107edae19405e76a299057668d795glennrp         for (x=0; x < ping_num_trans; x++)
2866c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
2867e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            image->colormap[x].opacity =
2868e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp              ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
2869c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2870c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2871faa852bad40107edae19405e76a299057668d795glennrp      else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2872c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
28735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         for (x=0; x < (int) image->colors; x++)
2874c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
287505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp            if (ScaleQuantumToShort(image->colormap[x].red) ==
287605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                transparent_color.opacity)
2877c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
2878c11cf6a442f3046940608a5743a68cc891deb13eglennrp               image->colormap[x].opacity = (Quantum) TransparentOpacity;
2879c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
2880c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2881c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2882d027259799c88ed5e4f12d21a5366031bfef0904cristy      (void) SyncImage(image);
2883c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2884c11cf6a442f3046940608a5743a68cc891deb13eglennrp   else
2885c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2886c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2887bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
2888c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2889c11cf6a442f3046940608a5743a68cc891deb13eglennrp        image->storage_class=storage_class;
2890c11cf6a442f3046940608a5743a68cc891deb13eglennrp        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2891c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (q == (PixelPacket *) NULL)
2892c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
28935c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2894c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
2896c11cf6a442f3046940608a5743a68cc891deb13eglennrp          {
289705eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp            if (ScaleQuantumToShort(q->red) == transparent_color.red &&
289805eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->green) == transparent_color.green &&
289905eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->blue) == transparent_color.blue)
2900c11cf6a442f3046940608a5743a68cc891deb13eglennrp               q->opacity=(Quantum) TransparentOpacity;
2901c11cf6a442f3046940608a5743a68cc891deb13eglennrp            else
2902c11cf6a442f3046940608a5743a68cc891deb13eglennrp              SetOpacityPixelComponent(q,OpaqueOpacity);
2903c11cf6a442f3046940608a5743a68cc891deb13eglennrp            q++;
2904c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
2905c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (SyncAuthenticPixels(image,exception) == MagickFalse)
2906c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
2907c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2908c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2909c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2910c11cf6a442f3046940608a5743a68cc891deb13eglennrp#else /* not balfour */
2911c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2912c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2913bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->storage_class=storage_class;
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
29195c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (storage_class == PseudoClass)
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexPacket
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexpacket;
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2926faa852bad40107edae19405e76a299057668d795glennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2927bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
29295c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2930faa852bad40107edae19405e76a299057668d795glennrp                if (indexpacket < ping_num_trans)
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=ScaleCharToQuantum((unsigned char)
2932bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    (255-ping_trans_alpha[(ssize_t) indexpacket]));
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2934ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2937faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2938bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
29405c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2941bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                q->red=image->colormap[(ssize_t) indexpacket].red;
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=q->red;
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=q->red;
294405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                if (ScaleQuantomToShort(q->red) == transparent_color.opacity)
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) TransparentOpacity;
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2947ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
2952bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
295405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp            if (ScaleQuantumToShort(q->red) == transparent_color.red &&
295505eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->green) == transparent_color.green &&
295605eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp                ScaleQuantumToShort(q->blue) == transparent_color.blue)
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               q->opacity=(Quantum) TransparentOpacity;
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2959ce70c17bb6433add2eb069515a4f3105989e0662cristy              SetOpacityPixelComponent(q,OpaqueOpacity);
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2965c11cf6a442f3046940608a5743a68cc891deb13eglennrp#endif /* not balfour */
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2968b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2969b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2970b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
301773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
3050faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
3052faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3053faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3054faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3055faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3056faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3057faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3058faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3059faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
3060faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3090f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
314973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3355e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3356e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3367bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3384bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3401f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3403f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
344673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
346673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk to color_image->blob
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy IDAT header and chunk data to alpha_image->blob
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3543bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk data to alpha_image->blob
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
36048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
36148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
36158182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
36168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
36178182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
36188182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
36198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
36208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3630e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3631e610a071534e448c46460a5aa39ede33bf56b329glennrp              PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.x=mng_get_long(p);
36518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->page.y=mng_get_long(&p[4]);
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36678182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
36688182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
3746bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3788bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the JNG image.
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.width=jng_width;
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.height=jng_height;
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.x=mng_info->x_off[mng_info->object_id];
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify JNG signature.
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
391573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3973bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3998bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4004bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4021bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403038ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
403138ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
403238ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4033bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    following optimizations:
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  16-bit depth is reduced to 8 if all pixels contain samples whose
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       high byte and low byte are identical.
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Opaque matte channel is removed.
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  If matte channel is present but only one transparent color is
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       present, RGB+tRNS is written instead of RGBA
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       this can be done without loss.
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Palette is sorted to remove unused entries and to put a
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       transparent color first, if PNG_SORT_PALETTE is also defined.
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
409073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->optimize=image_info->type == OptimizeType;
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Verify MNG signature.
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize some nonzero members of the MngInfo structure.
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4119bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4120bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4166e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4167e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4180bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4219bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
4221bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4226e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4228e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
42318182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
42428182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
4268e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4269e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4270f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4272bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4274bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42928182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
42938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4304e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4306e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4350bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) | (p[5] << 16) |
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
4352bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) | (p[9] << 16) |
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[10] << 8) | p[11]);
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4358f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4360e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4361f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global PLTE.
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
4424bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
443035ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
445912560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44708182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global cHRM
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44878182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
44888182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
44898182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
44918182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
44938182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
44958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
44978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
44998182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4514e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4515e610a071534e448c46460a5aa39ede33bf56b329glennrp                  PNG_RenderingIntent_to_Magick_RenderingIntent(p[0]);
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Note the delay and frame clipping boundaries.
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
4557bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
4560bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
45748182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
45758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
45768182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
4577bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4578bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4584e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4588bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4589bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
4590bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4591bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
4592bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4593bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4599e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4608e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Frame_clipping: L=%.20g R=%.20g T=%.20g B=%.20g",
4609e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4610e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
4618bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
4620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4628e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4629e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4668e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4669e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4670e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read DISC or SEEK.
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4744bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              read MOVE
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4753bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4776bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Record starting point.
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47828182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4785e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
4786e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4820e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        "  ENDL: LOOP level %.20g has %.20g remaining iterations ",
4821e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
4822f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
50048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
50068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5029bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5031bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
50958182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
50968182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5109bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5111bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Make a background rectangle.
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5150e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5151e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5197e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  Inserted background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5198e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5199e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
5248bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
53054e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                   magnified_width += (png_uint_32) ((image->columns-2)*(mng_info->magn_mx));
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53094e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
53154e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                   magnified_width += (png_uint_32) ((image->columns-3)*(mng_info->magn_mx-1));
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
53234d368204aa5ac1b8716da0054988319952030438cristy                   magnified_height += (png_uint_32) ((image->rows-2)*(mng_info->magn_my));
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53274e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
53334e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                   magnified_height += (png_uint_32) ((image->rows-3)*(mng_info->magn_my-1));
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5344bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5348bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5393bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
5397bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5433e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5434bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
5449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
5453bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5454bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5455bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5456bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5460bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
5464bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
5481bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
54835c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5505bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5511bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5514bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5535bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5565e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5567bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
5575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5578bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5579bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
5580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5584bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5587bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5607bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5613bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
5657bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
5713bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
5714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* Determine if bit depth can be reduced from 16 to 8.
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * Note that the method GetImageDepth doesn't check background
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * and doesn't handle PseudoClass specially.  Also it uses
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * multiplication and division by 257 instead of shifting, so
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * might be slower.
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->optimize && image->depth == 16)
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ok_to_reduce;
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const PixelPacket
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *p;
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5768bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ok_to_reduce=(((((size_t) image->background_color.red >> 8) &
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     0xff)
5770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.red & 0xff)) &&
5771bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.green >> 8) & 0xff)
5772bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.green & 0xff)) &&
5773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.blue >> 8) & 0xff)
5774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.blue & 0xff)));
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce && image->storage_class == PseudoClass)
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int indx;
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5779bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (indx=0; indx < (ssize_t) image->colors; indx++)
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5781bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    8) & 0xff)
5783bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5784bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5787bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].blue & 0xff)));
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == MagickFalse)
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((ok_to_reduce != MagickFalse) &&
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->storage_class != PseudoClass))
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5795bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              y;
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              x;
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5801bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (y=0; y < (ssize_t) image->rows; y++)
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5806bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=((
5809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->red >> 8) & 0xff) ==
5810bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->red & 0xff)) &&
5811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->green >> 8) & 0xff) ==
5812bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->green & 0xff)) &&
5813bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->blue >> 8) & 0xff) ==
5814bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->blue & 0xff)) &&
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((!image->matte ||
5816bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->opacity >> 8) & 0xff) ==
5817bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->opacity & 0xff)))));
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == 0)
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (x != 0)
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce)
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->depth=8;
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Reducing PNG bit depth to 8 without loss of info");
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
5839bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5957e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
5958e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5974e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5986bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6035e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6036e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6038f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6039f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
6040f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6041e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6042e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6043f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6044f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
605225c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
606525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6088bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6091bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
621318b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
621418b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
621518b17443128598500357da7bff2f01683cf32890cristy#endif
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6247514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6248514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
625325c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6339bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
6360e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy     (void) printf("writing raw profile: type=%s, length=%.20g\n",
6361e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy       (char *) profile_type, (double) length);
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6381f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
6383bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (LocaleNCompare(name,string,11) == 0) {
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Found %s profile",name);
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=CloneStringInfo(profile);
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data=GetStringInfoDatum(png_profile),
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       length=(png_uint_32) GetStringInfoLength(png_profile);
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[4]=data[3];
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[3]=data[2];
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[2]=data[1];
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[1]=data[0];
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,length-5);  /* data length */
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,length-1,data+1);
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=DestroyStringInfo(png_profile);
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6467cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6468cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6469e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6470e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
64715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     palette;
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
64765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
64775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
64785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
64865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
64875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
64885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6489bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
64995c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
65135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_bit_depth,
65145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
65155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
65165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
65175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
65185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
65195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6520bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
65225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
65235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6525bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6534f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
65385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=0,
65395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
65405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
65415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
65425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
65435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
65445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
65455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
65465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
65475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
65485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
65495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
65505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
65515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
65525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
65535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
65545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
65555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6556ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_colors=image->colors;
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=image->depth;
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_matte=image->matte;
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->IsPalette=image->storage_class == PseudoClass &&
65641449ea221d08431e12b667713077313a49000dc8cristy    image_colors <= 256 && !IsOpaqueImage(image,&image->exception);
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->optimize=image_info->type == OptimizeType;
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6600f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
66174e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
66184e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6633e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6635e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6637e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6639e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth=%.20g",(double) image->depth);
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6641e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    requested PNG image_depth=%.20g",(double) image->depth);
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
66445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution);
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution);
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_UNKNOWN;
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) image->x_resolution;
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) image->y_resolution;
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up pHYs chunk");
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x || image->page.y)
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (png_int_32) image->page.y, 0);
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up oFFs chunk");
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_color_16
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        background;
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_depth < MAGICKCORE_QUANTUM_DEPTH)
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6697bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             maxval;
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          maxval=(1UL << image_depth)-1;
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=(png_uint_16)
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.red));
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=(png_uint_16)
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.green));
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=(png_uint_16)
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.blue));
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=(png_uint_16)
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*PixelIntensity(&image->background_color)));
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=image->background_color.red;
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=image->background_color.green;
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=image->background_color.blue;
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_16) PixelIntensity(&image->background_color);
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      background.index=(png_byte) background.gray;
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Setting up bKGd chunk");
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_bKGD(ping,ping_info,&background);
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
672979f9995ecaa0e0daae607e9e88f257706730084dcristy  if ((mng_info->write_png_colortype-1) == PNG_COLOR_TYPE_PALETTE)
673079f9995ecaa0e0daae607e9e88f257706730084dcristy    mng_info->write_png8=MagickTrue;
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
67345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_bit_depth=8;
67355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: make this a function cause it's used twice, except
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             for reducing the sample depth from 8. */
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          QuantizeInfo
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantize_info;
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             number_colors,
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             save_number_colors;
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image->storage_class == DirectClass) || (number_colors > 256))
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GetQuantizeInfo(&quantize_info);
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MagickFalse ? MagickTrue : MagickFalse;
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                256UL);
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) QuantizeImage(&quantize_info,image);
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors=image_colors;
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) SyncImage(image);
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6760e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    Colors quantized to %.20g",(double) number_colors);
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
67635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Set image palette.
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
67675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          save_number_colors=image_colors;
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (CompressColormapTransFirst(image) == MagickFalse)
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
677298156a3a465a004545e39434c63052b955a74d1cglennrp          number_colors=image->colors;
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=save_number_colors;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_color *) AcquireQuantumMemory(257,
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*palette));
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (palette == (png_color *) NULL)
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
678198156a3a465a004545e39434c63052b955a74d1cglennrp                "  Setting up PLTE chunk with %d colors",
678298156a3a465a004545e39434c63052b955a74d1cglennrp                (int) number_colors);
6783bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) number_colors; i++)
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %3ld (%3d,%3d,%3d)",
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %5ld (%5d,%5d,%5d)",
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6795f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                (long) i,palette[i].red,palette[i].green,palette[i].blue);
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors++;
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_colorp) RelinquishMagickMemory(palette);
68075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            image_depth=ping_bit_depth;
68085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              int
68155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                trans_alpha[256];
68165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
6821bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
68225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 trans_alpha[i]=255;
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
6824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register const PixelPacket
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *p;
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetAuthenticPixels(image,0,y,image->columns,1,exception);
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (PixelPacket *) NULL)
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
68325c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexes=GetAuthenticIndexQueue(image);
6833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
68375c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      indexes[x]=(IndexPacket) (number_colors-1);
6838bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans_alpha[(ssize_t) indexes[x]]=(png_byte) (255-
6839ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (SyncAuthenticPixels(image,exception) == MagickFalse)
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
6846bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
68475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if (trans_alpha[i] != 255)
68485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=(unsigned short) (i+1);
68495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
68515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 png_set_invalid(ping, ping_info, PNG_INFO_tRNS);
68525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping, ping_info, PNG_INFO_tRNS))
68535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
68545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
68555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                {
68565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  for (i=0; i<256; i++)
68575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                     ping_trans_alpha[i]=(png_byte) trans_alpha[i];
68585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                }
68595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
68605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (void) png_set_tRNS(ping, ping_info,
68615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  ping_trans_alpha,
68625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  ping_num_trans,
68635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  &ping_trans_color);
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Identify which colormap entry is the background color.
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
6868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
68695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (IsPNGColorEqual(ping_background,image->colormap[i]))
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
68715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_background.index=(png_byte) i;
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
68815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
68865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
6894b905e45f528487c0e1c2a28b86b89f8ed86433a0cristy          image_matte=MagickFalse;
68955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
68965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "Selecting PNG colortype");
69045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) ((matte == MagickTrue)?
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         "Selected PNG colortype=%d",ping_color_type);
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
69395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
69405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB ||
69415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
69425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=8;
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
69525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (ping_bit_depth < (int)mng_info->write_png_depth)
69535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth = mng_info->write_png_depth;
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
695935ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
69605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
69610f111984738842d27d04aed2a3f823d82a943506glennrp
69620f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
69630f111984738842d27d04aed2a3f823d82a943506glennrp           {
69640f111984738842d27d04aed2a3f823d82a943506glennrp              /* DO SOMETHING */
69650f111984738842d27d04aed2a3f823d82a943506glennrp              (void) ThrowMagickException(&image->exception,
69660f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
69670f111984738842d27d04aed2a3f823d82a943506glennrp                "image has 0 colors", "`%s'","");
69680f111984738842d27d04aed2a3f823d82a943506glennrp           }
69690f111984738842d27d04aed2a3f823d82a943506glennrp
69700f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
69710f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69720f111984738842d27d04aed2a3f823d82a943506glennrp                  "  SyncImage.2.");
697335ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
69745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6979e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "    Number of colors: %.20g",(double) image_colors);
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                "    Tentative PNG bit depth: %d",ping_bit_depth);
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
69855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               old_bit_depth=ping_bit_depth;
69865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               if (ping_bit_depth < (int)mng_info->write_png_depth)
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
69885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth = mng_info->write_png_depth;
69895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth > 8)
69905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth = 8;
69915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth != (int) old_bit_depth)
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6995e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                           "    Colors increased to %.20g",(double)
6996f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                           image_colors);
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7006e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7008e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7010e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7012e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (matte && (mng_info->optimize || mng_info->IsPalette))
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
70215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
7022bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7027bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7045bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (x != 0)
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7054bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((y == (ssize_t) image->rows) && (x == (ssize_t) image->columns))
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
70605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type&=0x03;
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
70685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 8)
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
70705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 4)
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
70725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 2)
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
70745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 1)
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
70765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.red=(png_uint_16)
7077ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetRedPixelComponent(p)) & mask);
70785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.green=(png_uint_16)
7079ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetGreenPixelComponent(p)) & mask);
70805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.blue=(png_uint_16)
7081ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetBluePixelComponent(p)) & mask);
70825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.gray=(png_uint_16)
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
70845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.index=(png_byte)
708546f08209f719f4adeea742c45873c2714e80cdb9cristy            (ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))));
70865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (void) png_set_tRNS(ping, ping_info, NULL, 0,
70875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             &ping_trans_color);
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
70895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
7095bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
7102bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p) == 0)
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for multiple
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent colors.  */
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                semitransparency. */
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               else
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p))
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7126217484eb7236f4f3527af0feb39a6dc19a3302fecristy            if (x >= 0)
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7129217484eb7236f4f3527af0feb39a6dc19a3302fecristy          if (x >= 0)
71305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
71345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
71375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
71385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
71395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
71405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
71455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((mng_info->optimize || mng_info->IsPalette) &&
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
715135ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
71539c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
71565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
71585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray*=0x0101;
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
716335ef824baa82511126ff0072ae30eee0da9c05a3cristy          image_colors=one << image_depth;
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
71655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
71685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
71695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
71735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
717435ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
7175bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
71765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (mng_info->optimize && ping_color_type ==
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7190bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
72059c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
72079c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
72099c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7217bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
721817a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
721917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
722017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
722117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
72275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
72309c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
72319c1eb0729653219b9da9037e044501a6dce79d10glennrp                if (logging)
72329c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72339c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
7238bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   save_number_colors;
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->optimize)
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    save_number_colors=image_colors;
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (CompressColormapTransFirst(image) == MagickFalse)
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       ThrowWriterException(ResourceLimitError,
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                            "MemoryAllocationFailed");
724798156a3a465a004545e39434c63052b955a74d1cglennrp                    number_colors=image->colors;
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image_colors=save_number_colors;
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_color *) AcquireQuantumMemory(257,
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sizeof(*palette));
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (palette == (png_color *) NULL)
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
7256bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging)
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
726498156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
726598156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_colorp) RelinquishMagickMemory(palette);
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7272befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
7273befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
7274befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
72755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
7276befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
7277befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
72785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const PixelPacket
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p;
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[256];
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const IndexPacket
72935c6f789db7a30bad01ace12b09ad9cd471339e94cristy                *packet_indexes;
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
7299bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[i]=256;
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
7302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (const PixelPacket *) NULL)
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
73075c6f789db7a30bad01ace12b09ad9cd471339e94cristy                packet_indexes=GetVirtualIndexQueue(image);
7308bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      IndexPacket
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        packet_index;
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73155c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      packet_index=packet_indexes[x];
7316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      assert((size_t) packet_index < number_colors);
7317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      if (trans[(ssize_t) packet_index] != 256)
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
7319bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                          if (trans[(ssize_t) packet_index] != (png_byte) (255-
7320ce70c17bb6433add2eb069515a4f3105989e0662cristy                             ScaleQuantumToChar(GetOpacityPixelComponent(p))))
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
73225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                              ping_color_type=(png_byte)
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                PNG_COLOR_TYPE_RGB_ALPHA;
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              break;
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
7327bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans[(ssize_t) packet_index]=(png_byte) (255-
7328ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
73325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
73345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=0;
73355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
73365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_PLTE);
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->IsPalette=MagickFalse;
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) SyncImage(image);
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (logging)
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "    Cannot write image as indexed PNG, writing RGBA.");
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
73455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7347bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] == 256)
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    trans[i]=255;
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] != 255)
73525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_num_trans=(unsigned short) (i+1);
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
73555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
73565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
73575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
73585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
73595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
73609c1eb0729653219b9da9037e044501a6dce79d10glennrp                {
73619c1eb0729653219b9da9037e044501a6dce79d10glennrp                  for (i=0; i < (ssize_t) number_colors; i++)
73629c1eb0729653219b9da9037e044501a6dce79d10glennrp                      ping_trans_alpha[i]=(png_byte) trans[i];
73639c1eb0729653219b9da9037e044501a6dce79d10glennrp                }
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
73745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
73755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
73765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
73775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
73845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_color_16
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           background;
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
739335ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
739435ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
739535ef824baa82511126ff0072ae30eee0da9c05a3cristy
739622ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         background.gray=(png_uint_16)
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Setting up bKGD chunk");
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_set_bKGD(ping,ping_info,&background);
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
74085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
741017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
741117a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
741217a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
741317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
741417a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
741517a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
741617a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7417bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
741817a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
741917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
742017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
742117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
742317a1485544c62993fc7a94e343c87fed5f3e6407glennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
742417a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
742517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
742617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
742717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
742817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        if (logging)
742917a1485544c62993fc7a94e343c87fed5f3e6407glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
743017a1485544c62993fc7a94e343c87fed5f3e6407glennrp            "  Setting up bKGD chunk with index=%d",(int) i);
743117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
743217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        png_set_bKGD(ping,ping_info,&ping_background);
743317a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
743417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up deflate compression");
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression buffer size: 32768");
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
74573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7459bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
74683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
74835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter=PNG_ALL_FILTERS;
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((quality % 10) != 5)
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
75005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
75015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_NO_FILTERS;
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_ALL_FILTERS;
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
7553e610a071534e448c46460a5aa39ede33bf56b329glennrp      (void) png_set_sRGB(ping,ping_info,(
7554e610a071534e448c46460a5aa39ede33bf56b329glennrp        PNG_RenderingIntent_from_Magick_RenderingIntent(
7555e610a071534e448c46460a5aa39ede33bf56b329glennrp        image->rendering_intent)));
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
76095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
76105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
76115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
76165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
76205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
76225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
7623991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
76245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
76335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
76405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76433bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && !image->matte)
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
7652b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
7653b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7654b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7657e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  if (image->matte == MagickTrue && ping_color_type < 4)
7658e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
7659e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp      if (ping_color_type == 3 && ping_num_trans == 0)
7660e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp        {
7661e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
7662e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp          if (logging != MagickFalse)
7663e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7664e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp              "  Ignoring request to write tRNS chunk with num_trans==0");
7665e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp        }
7666e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp      else
7667e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp        (void) png_set_tRNS(ping, ping_info,
7668e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp                            ping_trans_alpha,
7669e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp                            ping_num_trans,
7670e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp                            &ping_trans_color);
7671e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
7672e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
76785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
76795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
76805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
76815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76919c1eb0729653219b9da9037e044501a6dce79d10glennrp      unsigned char
76929c1eb0729653219b9da9037e044501a6dce79d10glennrp        chunk[14];
76939c1eb0729653219b9da9037e044501a6dce79d10glennrp
76949c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
76959c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGType(chunk,mng_vpAg);
76969c1eb0729653219b9da9037e044501a6dce79d10glennrp      LogPNGChunk((int) logging,mng_vpAg,9L);
76979c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+4,(png_uint_32) image->page.width);
76989c1eb0729653219b9da9037e044501a6dce79d10glennrp      PNGLong(chunk+8,(png_uint_32) image->page.height);
76999c1eb0729653219b9da9037e044501a6dce79d10glennrp      chunk[12]=0;   /* unit = pixels */
77009c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlob(image,13,chunk);
77019c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
77059c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
77079c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
7716b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
7717b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
77187202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7720b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
7722b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7723b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
7724b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
7725b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7726b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
7728b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7729b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
7730b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7732b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (logging)
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7734b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7735b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
7736b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7737e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
77465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7761f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7765ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
7766ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
7767ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mng_info->optimize || mng_info->IsPalette ||
77743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
77813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
7786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
77953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
77963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
77973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
77983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
7800bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
78013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
78093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
7811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
78123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
7814b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7815b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7816b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
78223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
78263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
78313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
78365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7839bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
78445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
7852b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7853b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7854b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                     "    Writing GRAY PNG pixels (2)");
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7858b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7859b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7860b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (2)");
78613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7864b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7865b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7866b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (2)");
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
78813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
7882bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
78875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
78893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
78903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
78923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
78965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7897b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
7898b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
7899b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
7900b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                if (logging && y == 0)
7901b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7902b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (3)");
7903b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
7910b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            if (logging && y == 0)
7911b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7912b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "    Writing row of pixels (3)");
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
79173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
79215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
79223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging)
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7931e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp            if (logging && y == 0)
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
79375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
79405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7941b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
794207cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp                if (logging && y == 0)
7943b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7944b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "  Writing GRAY_ALPHA PNG pixels (4)");
7945b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
7946b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
7947b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
795107cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp            if (logging && y == 0)
7952b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7953b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "  Writing row of pixels (4)");
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7965b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
7966b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7971b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7973e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7975e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
79883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
80023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
80063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
80083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
80153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
80303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
80365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
80375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
80433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
80453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
80473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
80503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
80523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
80553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
80585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
80603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
80615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
80673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
80683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
80763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  s[0]=(char) ping_bit_depth;
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8093f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
81003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               channel is present even if the image is fully opaque.
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               from the application programming interfaces.
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Allow all other PNG subformats to be requested via new
81873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "-define png:bit-depth -define png:color-type" options.
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
81953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
81993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  subsequent profiles from overwriting the preceding ones:
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
82093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
82233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
824673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82649c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
82659c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
82669c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0 /* this does not work */
82689c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
82699c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,PaletteMatteType);
82709c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
82719c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,PaletteType);
82729c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82789c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
82799c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
82809c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
82819c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
82829c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
82839c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
82849c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
82859c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82909c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
82919c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
82929c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
82939c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
82949c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
82959c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
82969c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
82979c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
83023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
83049c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
83069c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
83089c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
83109c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
83129c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
83133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
83149c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83159c1eb0729653219b9da9037e044501a6dce79d10glennrp          "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
83213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
83229c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
83249c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
83269c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
83289c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
83309c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
83329c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83339c1eb0729653219b9da9037e044501a6dce79d10glennrp          "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
83903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
84273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
84313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
84363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
84483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
84493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
84543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
84683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
84753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
8481f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8485e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
8486e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
84913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
84994e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
85004e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
85113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8514f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8516f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-b profiles */
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
85373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
85403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
85433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
85463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
85513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8553bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
85543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
85583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
8560bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
8562bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    LogPNGChunk((int) logging,mng_bKGD,(size_t) (num_bytes-4L));
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
8585e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
8586e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
8587e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
8589e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
8590e610a071534e448c46460a5aa39ede33bf56b329glennrp          PNG_RenderingIntent_from_Magick_RenderingIntent(
8591e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
860535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
86193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
862235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
862335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
862535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
862635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
862835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
862935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
863135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
863235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
864735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
864935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
865735ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
865935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
866535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
866635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
8682bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
8683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8705bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8714e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
8715f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
8720bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
8727bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
8728bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                LogPNGChunk((int) logging,mng_IDAT,(size_t) len);
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8737e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
8738e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8748e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
8749bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8787e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
8788e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8802e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
8803e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8806e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
8809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
88183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
88713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
889673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8952bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8962bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8965bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8969d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
899273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=MagickFalse;
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=(image_info->type == OptimizeType || image_info->type ==
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      UndefinedType);
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (optimize)
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: TRUE");
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: FALSE");
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9046e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9054e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9056e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9071e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sometimes we get PseudoClass images whose RGB values don't match
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    the colors in the colormap.  This code syncs the RGB values.
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Image
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p;
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p->taint && p->storage_class == PseudoClass)
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(p);
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->adjoin == MagickFalse)
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_BUILD_PALETTE
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (optimize)
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Sometimes we get DirectClass images that have 256 colors or fewer.
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        This code will convert them to PseudoClass and build a colormap.
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class != PseudoClass)
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p->colors <= 256)
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p->colors=0;
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p->matte != MagickFalse)
91169c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) SetImageType(p,PaletteMatteType);
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
91189c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) SetImageType(p,PaletteType);
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
92870261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
9288d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
9289d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
9290d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
9291d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
9292d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
9293d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
9294d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
92953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
92963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
93004e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->ticks_per_second=(png_uint_32) (image->ticks_per_second/final_delay);
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
93274e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
93284e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
9380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
9381bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         LogPNGChunk((int) logging,mng_nEED,(size_t) length);
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9407e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
9408e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9411e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9414e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
9432e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
9433e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
9434e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
9436e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
9437e610a071534e448c46460a5aa39ede33bf56b329glennrp             PNG_RenderingIntent_from_Magick_RenderingIntent(
9438e610a071534e448c46460a5aa39ede33bf56b329glennrp             (PerceptualIntent));
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
945335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
947035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
947135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
947335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
947435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
947635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
947735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
947935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
948035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
949635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
949835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
950635ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
950835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
95113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
951435ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
951535ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
95193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
95203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
95233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
95263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
95443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
95553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
9558bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
95653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
9568bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
95733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
95793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
95813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
95823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
95833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
95843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
95863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
95883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
95893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
95913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
95923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
95973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
95993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
96023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
96033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
96103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
9611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
96123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
96133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
96153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
96163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
96173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
9618bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
96193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
96203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
96213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
96223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
96233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
96243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
96253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
96263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
96273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
96353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
96373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
96383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
96393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
96413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
96443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
96483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
96493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
96513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
96523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
96533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
96543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
96553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
96563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
96573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
96583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
96593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
96603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
96613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
96623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
96633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
96643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
96653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
96663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
96673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
96683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
96703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
96723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
96733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
96743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
96753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
96763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
96773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
96783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
96793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
96803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
96813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
96823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
96833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
96843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
96853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
96863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
96873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
96883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
96893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
96923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
96933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
96943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
96953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
96963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
96973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
96983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
96993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
97023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
97053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
97063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
97073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
97083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
97094e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
97103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
97113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
97163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
97173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
97193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
97263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
97273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
97283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
97293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
97303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
97333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
97353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
97363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
97373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
97403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
97433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
97453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
97463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
97473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
97483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
97493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
97503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
97513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
97523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
97533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
97543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
97563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
97573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
97583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
97593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
97603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
97613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
97623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
97633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
97643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
97653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
97673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
97683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
97693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
97703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
97713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
97733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
97743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9775d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
97763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
97773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
97783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
97793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
97803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
97813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
97823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
97833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
97843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
97853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
97873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9788d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
97893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9790