png.c revision 61b4c957269727a0a2526edc2331881da8346100
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%                                                                             %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Copyright 1999-2009 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"
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/enhance.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/geometry.h"
57f2e1166e90de2dfe2e6a2aed7cd5f73640f34a7acristy#include "magick/histogram.h"
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/layer.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/profile.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/property.h"
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantize.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/resource_.h"
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/semaphore.h"
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/static.h"
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/statistic.h"
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h"
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/transform.h"
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/utility.h"
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
82286a6355c4544b794da2b6df973faad07c69e541glennrp
837ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
847ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
857ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * migration to libpng-2.0, remove these defines and then
867ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
877ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
887ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp#define PNG_DEPRECATED  /* Use of this function is deprecated */
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp#define PNG_USE_RESULT  /* The result of this function must be checked */
907ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp#define PNG_NORETURN    /* This function does not return */
917ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp#define PNG_ALLOCATED   /* The result of the function is new memory */
927ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp#define PNG_DEPSTRUCT   /* Access to this struct member is deprecated */
93286a6355c4544b794da2b6df973faad07c69e541glennrp
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER < 10400
1012c74c978809443456f5a21cd43b25b0a55c7881aglennrp#    define trans_color  trans_values   /* Changed at libpng-1.4.0beta35 */
1022c74c978809443456f5a21cd43b25b0a55c7881aglennrp#    define trans_alpha  trans          /* Changed at libpng-1.4.0beta74 */
1032c74c978809443456f5a21cd43b25b0a55c7881aglennrp#else
1042c74c978809443456f5a21cd43b25b0a55c7881aglennrp   /* We could parse PNG_LIBPNG_VER_STRING here but it's too much bother..
1052c74c978809443456f5a21cd43b25b0a55c7881aglennrp    * Just don't use libpng-1.4.0beta32-34 or beta67-73
1062c74c978809443456f5a21cd43b25b0a55c7881aglennrp    */
1072c74c978809443456f5a21cd43b25b0a55c7881aglennrp#  ifndef  PNG_USER_CHUNK_CACHE_MAX     /* Added at libpng-1.4.0beta32 */
1082c74c978809443456f5a21cd43b25b0a55c7881aglennrp#    define trans_color  trans_values   /* Changed at libpng-1.4.0beta35 */
1092c74c978809443456f5a21cd43b25b0a55c7881aglennrp#  endif
1102c74c978809443456f5a21cd43b25b0a55c7881aglennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
1112c74c978809443456f5a21cd43b25b0a55c7881aglennrp#    define trans_alpha  trans          /* Changed at libpng-1.4.0beta74 */
1122c74c978809443456f5a21cd43b25b0a55c7881aglennrp#  endif
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_BUILD_PALETTE   /* This works as of 5.4.3. */
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SORT_PALETTE    /* This works as of 5.4.0. */
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *png_semaphore = (SemaphoreInfo *) NULL;
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10009)  /* work around libpng-1.0.9 bug */
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  undef PNG_READ_EMPTY_PLTE_SUPPORTED
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  undef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Maximum valid unsigned long in PNG/MNG chunks is (2^31)-1
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile long
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline long MagickMax(const long x,const long y)
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic inline long MagickMin(const long x,const long y)
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   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                       %
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CompressColormapTransFirst compresses an image colormap removing
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  any duplicate and unused color entries and putting the transparent colors
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  first.  Returns MagickTrue on success, MagickFalse on error.
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CompressColormapTransFirst method is:
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned int CompressColormapTransFirst(Image *image)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType CompressColormapTransFirst(Image *image)
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    remap_needed,
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k;
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j,
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors,
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *colormap;
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const IndexPacket
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indices;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top_used;
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *map,
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *opacity;
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *marker,
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_transparency;
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if colormap can be compressed.
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class != PseudoClass || image->colors > 256 ||
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors < 2)
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) AcquireQuantumMemory(image->colors,sizeof(*marker));
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (marker == (unsigned char *) NULL)
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) AcquireQuantumMemory(image->colors,sizeof(*opacity));
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (opacity == (IndexPacket *) NULL)
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Mark colors that are present.
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  number_colors=(long) image->colors;
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    marker[i]=MagickFalse;
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    opacity[i]=OpaqueOpacity;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  top_used=0;
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    indices=GetVirtualIndexQueue(image);
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->matte != MagickFalse)
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (x=0; x < (long) image->columns; x++)
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        marker[(int) indices[x]]=MagickTrue;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        opacity[(int) indices[x]]=p->opacity;
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (indices[x] > top_used)
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           top_used=indices[x];
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p++;
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (x=0; x < (long) image->columns; x++)
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        marker[(int) indices[x]]=MagickTrue;
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (indices[x] > top_used)
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           top_used=indices[x];
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Mark background color, topmost occurrence if more than one.
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=number_colors-1; i; i--)
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsColorEqual(image->colormap+i,&image->background_color))
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          marker[i]=MagickTrue;
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Unmark duplicates.
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors-1; i++)
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            marker[j]=MagickFalse;
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Count colors that still remain.
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_transparency=MagickFalse;
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  new_number_colors=0;
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        new_number_colors++;
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (opacity[i] != OpaqueOpacity)
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          have_transparency=MagickTrue;
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!have_transparency || (marker[0] &&
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (opacity[0] == (Quantum) TransparentOpacity)))
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      && (new_number_colors == number_colors))
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        No duplicate or unused entries, and transparency-swap not needed.
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  remap_needed=MagickFalse;
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((long) top_used >= new_number_colors)
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     remap_needed=MagickTrue;
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress colormap.
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) AcquireQuantumMemory(image->colors,
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*colormap));
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (colormap == (PixelPacket *) NULL)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Eliminate unused colormap entries.
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) AcquireQuantumMemory((size_t) number_colors,
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*map));
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (map == (IndexPacket *) NULL)
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  k=0;
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    map[i]=(IndexPacket) k;
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               map[j]=(IndexPacket) k;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               marker[j]=MagickFalse;
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        k++;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=0;
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        colormap[j]=image->colormap[i];
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        j++;
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Move the first transparent color to palette entry 0.
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < number_colors; i++)
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PixelPacket
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              temp_colormap;
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            temp_colormap=colormap[0];
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[0]=colormap[(int) map[i]];
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[(long) map[i]]=temp_colormap;
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (j=0; j < number_colors; j++)
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (map[j] == 0)
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=map[i];
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else if (map[j] == map[i])
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=0;
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            remap_needed=MagickTrue;
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) RelinquishMagickMemory(marker);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (remap_needed)
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ExceptionInfo
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *exception;
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register IndexPacket
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *pixels;
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register PixelPacket
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *q;
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Remap pixels.
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=(&image->exception);
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=GetAuthenticIndexQueue(image);
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=0; x < (long) image->columns; x++)
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j=(int) pixels[x];
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels[x]=map[j];
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < new_number_colors; i++)
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i]=colormap[i];
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colors=(unsigned long) new_number_colors;
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) RelinquishMagickMemory(map);
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s G r a y                                                     %
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsGray(Image *image)
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < (long) image->colors; i++)
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsGray(image->colormap+i) == MagickFalse)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=(long) image->columns-1; x >= 0; x--)
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (IsGray(p) == MagickFalse)
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       p++;
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s M o n o c h r o m e                                         %
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   and is more accurate.                                                     %
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsMonochrome(Image *image)
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < (long) image->colors; i++)
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((IsGray(image->colormap+i) == MagickFalse) ||
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((image->colormap[i].red != 0) &&
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (image->colormap[i].red != (Quantum) QuantumRange)))
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=(long) image->columns-1; x >= 0; x--)
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 95)
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic size_t WriteBlobMSBULong(Image *image,const unsigned long value)
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing %c%c%c%c chunk, length: %lu",
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[0],type[1],type[2],type[3],(unsigned long) length);
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "Expected %lu bytes; found %lu bytes",(unsigned long) length,
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (unsigned long) check);
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) WriteBlob(image,(unsigned long) length,data);
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < (long) a->colors; i++)
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].right=(long) PNG_UINT_31_MAX;
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].bottom=(long) PNG_UINT_31_MAX;
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register long
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.left=(long) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.right=(long) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.top=(long) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box.bottom=(long) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read two longs from CLON, MOVE or PAST chunk
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic long mng_get_long(unsigned char *p)
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      message);
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=(png_uint_32) atol(sp);
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < (long) nibbles; i++)
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->page.width=(unsigned long) ((chunk->data[0] << 24) |
16103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->page.height=(unsigned long) ((chunk->data[4] << 24) |
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pass;
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indices;
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1728a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy  (void) LockSemaphoreInfo(png_semaphore);
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
173761b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
173861b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
173961b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
174061b4c957269727a0a2526edc2331881da8346100glennrp    {
174161b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
174261b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
174361b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
174461b4c957269727a0a2526edc2331881da8346100glennrp    }
174561b4c957269727a0a2526edc2331881da8346100glennrp#  endif
174661b4c957269727a0a2526edc2331881da8346100glennrp#endif
174761b4c957269727a0a2526edc2331881da8346100glennrp
174861b4c957269727a0a2526edc2331881da8346100glennrp
1749ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1785a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy      (void) UnlockSemaphoreInfo(png_semaphore);
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17910c38ae55173384e633408067dc1a40d38dd9bd9ccristy        image->columns=0;
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->bit_depth < 8)
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE))
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_packing(ping);
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=ping_info->bit_depth;
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->interlace=ping_info->interlace_type != 0 ? PNGInterlace : NoInterlace;
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG width: %lu, height: %lu",
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->width, ping_info->height);
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->color_type, ping_info->bit_depth);
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->compression_type);
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->interlace_type,ping_info->filter_type);
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008) && defined(PNG_READ_iCCP_SUPPORTED)
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_iCCP)
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        info,
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      intent;
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rendering_intent=(RenderingIntent)
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->global_srgb_intent+1);
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->rendering_intent=(RenderingIntent) (intent+1);
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Reading PNG sRGB chunk: rendering_intent: %d",intent+1);
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     double
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        file_gamma;
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->have_global_gama)
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       image->gamma=mng_info->global_gamma;
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_chrm != MagickFalse)
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->chromaticity=mng_info->global_chrm;
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_cHRM)
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->rendering_intent)
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->gamma=0.45455f;
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.red_primary.x=0.6400f;
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.red_primary.y=0.3300f;
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.green_primary.x=0.3000f;
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.green_primary.y=0.6000f;
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.blue_primary.x=0.1500f;
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.blue_primary.y=0.0600f;
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.white_point.x=0.3127f;
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->chromaticity.white_point.y=0.3290f;
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_global_gama != MagickFalse) || image->rendering_intent)
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ping_info->valid|=PNG_INFO_gAMA;
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_global_chrm != MagickFalse) || image->rendering_intent)
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ping_info->valid|=PNG_INFO_cHRM;
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_oFFs)
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=png_get_x_offset_pixels(ping, ping_info);
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=png_get_y_offset_pixels(ping, ping_info);
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Reading PNG oFFs chunk: x: %ld, y: %ld.",image->page.x,
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y);
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_pHYs)
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          &unit_type);
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->x_resolution=(float) x_resolution;
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->y_resolution=(float) y_resolution;
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG pHYs chunk: xres: %lu, yres: %lu, units: %d.",
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution, y_resolution, unit_type);
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->have_global_phys)
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(float) mng_info->global_x_pixels_per_unit;
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(float) mng_info->global_y_pixels_per_unit;
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_phys_unit_type == PNG_RESOLUTION_METER)
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->units=PixelsPerCentimeterResolution;
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->x_resolution=(double)
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit/100.0;
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->y_resolution=(double)
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit/100.0;
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid|=PNG_INFO_pHYs;
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_PLTE)
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE))
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((ping_info->valid & PNG_INFO_tRNS) == 0)
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->valid & PNG_INFO_bKGD)
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=ping_info->background.index;
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_bKGD_SUPPORTED)
20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_bkgd && !(ping_info->valid & PNG_INFO_bKGD))
20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_bKGD)
20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->bit_depth <= MAGICKCORE_QUANTUM_DEPTH)
20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=ping_info->background.red;
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=ping_info->background.green;
21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=ping_info->background.blue;
21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.red=
21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ScaleShortToQuantum(ping_info->background.red);
21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.green=
21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ScaleShortToQuantum(ping_info->background.green);
21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->background_color.blue=
21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ScaleShortToQuantum(ping_info->background.blue);
21103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.red=0;
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.green=0;
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.blue=0;
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent_color.opacity=0;
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_tRNS)
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      max_sample = (1 << ping_info->bit_depth) - 1;
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((ping_info->color_type == PNG_COLOR_TYPE_GRAY &&
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (int)ping_info->trans_color.gray > max_sample) ||
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->color_type == PNG_COLOR_TYPE_RGB &&
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ((int)ping_info->trans_color.red > max_sample ||
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (int)ping_info->trans_color.green > max_sample ||
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (int)ping_info->trans_color.blue > max_sample)))
21373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_alpha=(unsigned char *) RelinquishMagickMemory(
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_alpha);
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid&=(~PNG_INFO_tRNS);
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.red= (Quantum)(ping_info->trans_color.red);
21533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.green= (Quantum) (ping_info->trans_color.green);
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.blue= (Quantum) (ping_info->trans_color.blue);
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          transparent_color.opacity= (Quantum) (ping_info->trans_color.gray);
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->bit_depth < 8)
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
21603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  transparent_color.opacity=(Quantum) (((
21613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->trans_color.gray)*255)/max_sample);
21623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (!(ping_info->valid & PNG_INFO_sBIT))
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.right=(long) ping_info->width;
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.bottom=(long) ping_info->height;
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=ping_info->width;
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=ping_info->height;
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=ping_info->width;
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=ping_info->height;
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE) ||
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY))
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=1UL << ping_info->bit_depth;
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=256;
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 65536L)
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colors=65536L;
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->colors=(unsigned long) number_colors;
22223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) image->colors; i++)
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          scale=(QuantumRange/((1UL << ping_info->bit_depth)-1));
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) image->colors; i++)
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_info->number_scenes != 0) && (mng_info->scenes_found > (long)
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image_info->first_scene+image_info->number_scenes)))
22743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Skipping PNG image data for scene %ld",
22783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
22803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2281a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy      (void) UnlockSemaphoreInfo(png_semaphore);
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->rowbytes*sizeof(*png_pixels));
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_pixels=(unsigned char *) AcquireQuantumMemory(ping_info->rowbytes,
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sizeof(*png_pixels));
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2312a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy      (void) UnlockSemaphoreInfo(png_semaphore);
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
23220c38ae55173384e633408067dc1a40d38dd9bd9ccristy        image->columns=0;
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2325ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
2326ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2327ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert image to DirectClass pixel packets.
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        depth;
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      depth=(long) ping_info->bit_depth;
23393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=(((int) ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->valid & PNG_INFO_tRNS)) ? MagickTrue : MagickFalse;
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
23473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=ping_info->rowbytes*y;
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
2351abc8f408bb48da2d73cb760d61f16063695081d2cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (0 && (MAGICKCORE_QUANTUM_DEPTH == 8) && !defined(MAGICKCORE_HDRI_SUPPORT))
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 16)
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register Quantum
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *p,
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r;
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            r=png_pixels+row_offset;
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=r;
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=(long) image->columns-1; x >= 0; x--)
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((ping_info->valid & PNG_INFO_tRNS) &&
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (((*(p-2) << 8)|*(p-1)) == transparent_color.opacity))
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
23763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_RGB)
23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->valid & PNG_INFO_tRNS)
23823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=(long) image->columns-1; x >= 0; x--)
23833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
23893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if ((((*(p-6) << 8)|*(p-5)) == transparent_color.red) &&
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-4) << 8)|*(p-3)) == transparent_color.green) &&
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (((*(p-2) << 8)|*(p-1)) == transparent_color.blue))
23933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       /* Cheap transparency */
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=TransparentOpacity;
23963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
23973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
23983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       *r++=OpaqueOpacity;
23993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
24013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=(long) image->columns-1; x >= 0; x--)
24023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
24033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=*p++;
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=OpaqueOpacity;
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) (4*image->columns); x != 0; x--)
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) (2*image->columns); x != 0; x--)
24203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
24233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
24243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (depth == 8 && ping_info->color_type == PNG_COLOR_TYPE_GRAY)
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset);
24283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ping_info->color_type == PNG_COLOR_TYPE_GRAY ||
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GrayAlphaQuantum,png_pixels+row_offset);
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if (depth == 8 && ping_info->color_type == PNG_COLOR_TYPE_RGB)
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             RGBQuantum,png_pixels+row_offset);
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if (ping_info->color_type == PNG_COLOR_TYPE_RGB ||
24393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantum_info->depth=8;
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              RGBAQuantum,png_pixels+row_offset);
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
24453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if (ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              IndexQuantum,png_pixels+row_offset);
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* (MAGICKCORE_QUANTUM_DEPTH != 8) */
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY)
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayQuantum,png_pixels+row_offset,exception);
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if ((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GrayAlphaQuantum,png_pixels+row_offset,exception);
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if ((int) ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBAQuantum,png_pixels+row_offset,exception);
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexQuantum,png_pixels+row_offset,exception);
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
24633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            RGBQuantum,png_pixels+row_offset,exception);
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->previous == (Image *) NULL)
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
24773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
24803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
24833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
24863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=ping_info->rowbytes*y;
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
24993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
25003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        indices=GetAuthenticIndexQueue(image);
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (ping_info->bit_depth)
25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register long
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-7; x > 0; x-=8)
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-3; x > 0; x-=4)
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=3; i >= (long) (4-(image->columns % 4)); i--)
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-1; x > 0; x-=2)
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == 4)
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) image->columns-1; x >= 0; x--)
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
25623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) image->columns-1; x >= 0; x--)
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-1; x >= 0; x--)
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              unsigned long
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->color_type == 4)
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              unsigned long
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->color_type == 4)
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-q->opacity);
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->color_type == 4)
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=0; x < (long) image->columns; x++)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          indices[x]=(*r++);
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->previous == (Image *) NULL)
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2650b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2651b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SyncImage(image);
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (long) image_info->first_scene && image->delay != 0)
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2664a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy      (void) UnlockSemaphoreInfo(png_semaphore);
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_tRNS)
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->storage_class=storage_class;
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        indices=GetAuthenticIndexQueue(image);
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (storage_class == PseudoClass)
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexPacket
26923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexpacket;
26933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexpacket=indices[x];
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (indexpacket < ping_info->num_trans)
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=ScaleCharToQuantum((unsigned char)
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (255-ping_info->trans_alpha[(long) indexpacket]));
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=OpaqueOpacity;
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=0; x < (long) image->columns; x++)
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indexpacket=indices[x];
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->red=image->colormap[(long) indexpacket].red;
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=q->red;
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=q->red;
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (q->red == transparent_color.opacity)
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) TransparentOpacity;
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=OpaqueOpacity;
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (x=(long) image->columns-1; x >= 0; x--)
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ScaleQuantumToChar(q->red) == transparent_color.red &&
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->green) == transparent_color.green &&
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->blue) == transparent_color.blue)
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               q->opacity=(Quantum) TransparentOpacity;
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              q->opacity=OpaqueOpacity;
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->depth > 8)
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->depth=8;
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=0; i < (long) num_text; i++)
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
27633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
27653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
27683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
27803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
27823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireMagickMemory(sizeof(MngBuffer));
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
27913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
27993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_uint_32
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            width,
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            height;
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            bit_depth,
28123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            color_type,
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            interlace_method,
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            compression_method,
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            filter_method;
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
28203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_get_IHDR(ping,ping_info,&width,&height,&bit_depth,&color_type,
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &interlace_method,&compression_method,&filter_method);
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (width > 250000L || height > 250000L)
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->width=width;
28333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->height=height;
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->color_type=color_type;
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->sample_depth=bit_depth;
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->interlace_method=interlace_method;
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->compression_method=compression_method;
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->filter_method=filter_method;
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->valid & PNG_INFO_PLTE)
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
28513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
28593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
28663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2869a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy  (void) UnlockSemaphoreInfo(png_semaphore);
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
29043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
29403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
29413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
29423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
29463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
29473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Reading JNG chunk type %c%c%c%c, length: %lu",
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0],type[1],type[2],type[3],length);
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (i=0; i < (long) length; i++)
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_width:      %16lu",jng_width);
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_width:      %16lu",jng_height);
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireMagickMemory(sizeof(ImageInfo));
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
32543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk to color_image->blob
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy IDAT header and chunk data to alpha_image->blob
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,(unsigned long) length);
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk data to alpha_image->blob
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->gamma=((float) mng_get_long(p))*0.00001;
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rendering_intent=(RenderingIntent) (p[0]+1);
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_get_long(p);
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_get_long(&p[4]);
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->x_resolution=(double) mng_get_long(p);
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->y_resolution=(double) mng_get_long(&p[4]);
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
35023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
35063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
35073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (y=0; y < (long) image->rows; y++)
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
35373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           for (y=0; y < (long) image->rows; y++)
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               for (x=(long) image->columns; x != 0; x--,q++,s++)
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               for (x=(long) image->columns; x != 0; x--,q++,s++)
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the JNG image.
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.width=jng_width;
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.height=jng_height;
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.x=mng_info->x_off[mng_info->object_id];
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify JNG signature.
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile long
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned long
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    following optimizations:
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  16-bit depth is reduced to 8 if all pixels contain samples whose
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       high byte and low byte are identical.
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Opaque matte channel is removed.
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  If matte channel is present but only one transparent color is
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       present, RGB+tRNS is written instead of RGBA
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       this can be done without loss.
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Palette is sorted to remove unused entries and to put a
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       transparent color first, if PNG_SORT_PALETTE is also defined.
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->optimize=image_info->type == OptimizeType;
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Verify MNG signature.
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize some nonzero members of the MngInfo structure.
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->object_clip[i].right=(long) PNG_UINT_31_MAX;
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->object_clip[i].bottom=(long) PNG_UINT_31_MAX;
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Reading MNG chunk type %c%c%c%c, length: %lu",
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           type[0],type[1],type[2],type[3],length);
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) length; i++)
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->mng_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->mng_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  MNG width: %lu",mng_info->mng_width);
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  MNG height: %lu",mng_info->mng_height);
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ticks_per_second=(unsigned long) mng_get_long(p);
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                simplicity=(unsigned long) mng_get_long(p);
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu+0+0",
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->mng_width,mng_info->mng_height);
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.right=(long) mng_info->mng_width;
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.bottom=(long) mng_info->mng_height;
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    final_delay=%ld",final_delay);
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    image->iterations=%ld",image->iterations);
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->x_off[object_id]=(long) ((p[4] << 24) | (p[5] << 16) |
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->y_off[object_id]=(long) ((p[8] << 24) | (p[9] << 16) |
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[10] << 8) | p[11]);
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "  x_off[%d]: %lu",object_id,mng_info->x_off[object_id]);
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "  y_off[%d]: %lu",object_id,mng_info->y_off[object_id]);
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global PLTE.
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) (length/3); i++)
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_plte_length=length/3;
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) length; i++)
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->global_trns_length=length;
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                long
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                igamma=mng_get_long(p);
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global cHRM
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[12]);
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[16]);
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[20]);
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[24]);
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_get_long(&p[28]);
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_srgb_intent=(RenderingIntent) (p[0]+1);
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Note the delay and frame clipping boundaries.
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                while (*p && ((p-chunk) < (long) length))
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((p-chunk) < (long) (length-4))
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        frame_delay=(1UL*image->ticks_per_second*
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            (mng_get_long(p))/mng_info->ticks_per_second);
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Framing_delay=%ld",frame_delay);
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        frame_timeout=(1UL*image->ticks_per_second*
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            (mng_get_long(p))/mng_info->ticks_per_second);
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Framing_timeout=%ld",frame_timeout);
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Frame_clipping: L=%ld R=%ld T=%ld B=%ld",
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              fb.left, fb.right,fb.top,fb.bottom);
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            subframe_width=(unsigned long) (mng_info->clip.right
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            subframe_height=(unsigned long) (mng_info->clip.bottom
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "   subframe_width=%lu, subframe_height=%lu",
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                subframe_width, subframe_height);
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Inserted background layer, L=%ld, R=%ld, T=%ld, B=%ld",
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->clip.left,mng_info->clip.right,
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->clip.top,mng_info->clip.bottom);
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read DISC or SEEK.
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register long
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (j=0; j < (long) length; j+=2)
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned long
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              read MOVE
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(long) first_object; i <= (long) last_object; i++)
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            long loop_iters=1;
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Record starting point.
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_iters=mng_get_long(&chunk[1]);
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  LOOP level %ld  has %ld iterations ",loop_level,loop_iters);
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "  ENDL: LOOP level %ld  has %ld remaining iterations ",
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level,mng_info->loop_count[loop_level]);
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (unsigned long) mng_get_long(p);
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (unsigned long) mng_get_long(&p[4]);
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_width=(unsigned long) ((p[0] << 24) | (p[1] << 16) |
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_height=(unsigned long) ((p[4] << 24) | (p[5] << 16) |
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_width=(unsigned  long) mng_get_long(p);
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_height=(unsigned  long) mng_get_long(&p[4]);
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->clip.right < (long) mng_info->mng_width) ||
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->clip.bottom < (long) mng_info->mng_height))
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Make a background rectangle.
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Inserted transparent background layer, W=%lud, H=%lud",
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->mng_width,mng_info->mng_height);
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Inserted background layer, L=%ld, R=%ld, T=%ld, B=%ld",
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->clip.left,mng_info->clip.right,
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->clip.top,mng_info->clip.bottom);
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        offset=SeekBlob(image,-((long) length+12),SEEK_CUR);
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-2)*(mng_info->magn_mx);
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=image->columns;
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-3)*(mng_info->magn_mx-1);
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-2)*(mng_info->magn_my);
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=image->rows;
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-3)*(mng_info->magn_my-1);
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                long
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register long
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     for (y=0; y < (long) image->rows; y++)
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       for (x=(long) image->columns-1; x >= 0; x--)
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Magnify the rows to %lu",large_image->rows);
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                m=(long) mng_info->magn_mt;
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (y=0; y < (long) image->rows; y++)
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_mt;
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else if (magn_methy > 1 && y == (long) image->rows-2)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_mb;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else if (magn_methy <= 1 && y == (long) image->rows-1)
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_mb;
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else if (magn_methy > 1 && y == (long) image->rows-1)
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=(long) mng_info->magn_my;
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y < (long) image->rows-1)
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    assert(yy < (long) large_image->rows);
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (x=(long) image->columns-1; x >= 0; x--)
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /* TO DO: get color as function of indices[x] */
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) (((long) (2*i*((*n).red
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m))/((long) (m*2))
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) (((long) (2*i*((*n).green
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)+m))/((long) (m*2))
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) (((long) (2*i*((*n).blue
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m))/((long) (m*2))
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) (((long)
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 /((long) (m*2))+(*pixels).opacity);
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) (((long) (2*i*((*n).opacity
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))/((long) (m*2))
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Magnify the columns to %lu",image->columns);
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (y=0; y < (long) image->rows; y++)
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (x=(long) (image->columns-length);
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    x < (long) image->columns; x++)
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (x == (long) (image->columns-length))
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_ml;
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else if (magn_methx > 1 && x == (long) image->columns-2)
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_mr;
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else if (magn_methx <= 1 && x == (long) image->columns-1)
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_mr;
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else if (magn_methx > 1 && x == (long) image->columns-1)
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=(long) mng_info->magn_mx;
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 /((long) (m*2))+(*pixels).red);
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +m)/((long) (m*2))+(*pixels).green);
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 /((long) (m*2))+(*pixels).blue);
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   -(*pixels).opacity)+m)/((long) (m*2))
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
53793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m) /((long) (m*2))
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   for (y=0; y < (long) image->rows; y++)
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     for (x=(long) image->columns-1; x >= 0; x--)
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
54433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.width=(unsigned long) (crop_box.right-crop_box.left);
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.height=(unsigned long) (crop_box.bottom-crop_box.top);
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* Determine if bit depth can be reduced from 16 to 8.
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * Note that the method GetImageDepth doesn't check background
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * and doesn't handle PseudoClass specially.  Also it uses
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * multiplication and division by 257 instead of shifting, so
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * might be slower.
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->optimize && image->depth == 16)
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ok_to_reduce;
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const PixelPacket
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *p;
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ok_to_reduce=(((((unsigned long) image->background_color.red >> 8) &
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     0xff)
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          == ((unsigned long) image->background_color.red & 0xff)) &&
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ((((unsigned long) image->background_color.green >> 8) & 0xff)
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          == ((unsigned long) image->background_color.green & 0xff)) &&
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ((((unsigned long) image->background_color.blue >> 8) & 0xff)
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          == ((unsigned long) image->background_color.blue & 0xff)));
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce && image->storage_class == PseudoClass)
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int indx;
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (indx=0; indx < (long) image->colors; indx++)
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=(((((unsigned long) image->colormap[indx].red >>
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    8) & 0xff)
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  == ((unsigned long) image->colormap[indx].red & 0xff)) &&
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) image->colormap[indx].green >> 8) & 0xff)
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  == ((unsigned long) image->colormap[indx].green & 0xff)) &&
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) image->colormap[indx].blue >> 8) & 0xff)
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  == ((unsigned long) image->colormap[indx].blue & 0xff)));
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == MagickFalse)
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((ok_to_reduce != MagickFalse) &&
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->storage_class != PseudoClass))
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            long
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              y;
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            register long
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              x;
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (y=0; y < (long) image->rows; y++)
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (x=(long) image->columns-1; x >= 0; x--)
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=((
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((unsigned long) p->red >> 8) & 0xff) ==
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->red & 0xff)) &&
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) p->green >> 8) & 0xff) ==
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->green & 0xff)) &&
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((((unsigned long) p->blue >> 8) & 0xff) ==
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->blue & 0xff)) &&
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((!image->matte ||
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((unsigned long) p->opacity >> 8) & 0xff) ==
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ((unsigned long) p->opacity & 0xff)))));
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == 0)
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (x != 0)
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce)
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->depth=8;
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Reducing PNG bit depth to 8 without loss of info");
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (long) (image_info->first_scene+image_info->number_scenes))
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  image->delay=%lu, final_delay=%lu",image->delay,final_delay);
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    scene 0 delay=%lu",image->delay);
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    scene %d delay=%lu",++scene,image->delay);
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned long
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    scene 0 delay=%lu dispose=%d",image->delay,(int) image->dispose);
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=GetNextImageInList(image);
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    scene %d delay=%lu dispose=%d",++scene,
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay,(int) image->dispose);
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* PNG_LIBPNG_VER > 95 */
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned long RegisterPNGImage(void)
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport unsigned long RegisterPNGImage(void)
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
59313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
597318b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
597418b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
597518b17443128598500357da7bff2f01683cf32890cristy#endif
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  DestroySemaphoreInfo(&png_semaphore);
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if PNG_LIBPNG_VER > 95
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 99 && PNG_LIBPNG_VER < 10007)
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* This function became available in libpng version 1.0.6g. */
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_ptr->zbuf)
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf=NULL;
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_ptr->zbuf_size=(png_size_t) size;
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_ptr->zbuf=(png_bytep) png_malloc(png_ptr, size);
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_ptr->zbuf == 0)
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_error(png_ptr,"Unable to allocate zbuf");
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   register long
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER <= 10005)
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) printf("Not ");
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   image_info=image_info;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   ping=ping;
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   ping_info=ping_info;
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   profile_type=profile_type;
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   profile_description=profile_description;
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   profile_data=profile_data;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   length=length;
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) printf("writing raw profile: type=%s, length=%lu\n",
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (char *) profile_type, length);
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (png_size_t) (dp-text[0].text),"%8lu ",length);
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   for (i=0; i < (long) length; i++)
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (LocaleNCompare(name,string,11) == 0) {
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Found %s profile",name);
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=CloneStringInfo(profile);
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data=GetStringInfoDatum(png_profile),
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       length=(png_uint_32) GetStringInfoLength(png_profile);
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[4]=data[3];
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[3]=data[2];
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[2]=data[1];
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[1]=data[0];
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,length-5);  /* data length */
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,length-1,data+1);
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=DestroyStringInfo(png_profile);
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pass;
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     palette;
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  long
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *indices;
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned long
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_depth;
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_bit_depth,
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6303a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy  (void) LockSemaphoreInfo(png_semaphore);
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6306ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_colors=image->colors;
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=image->depth;
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_matte=image->matte;
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->IsPalette=image->storage_class == PseudoClass &&
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_colors <= 256;
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->optimize=image_info->type == OptimizeType;
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
63373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6350a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy      (void) UnlockSemaphoreInfo(png_semaphore);
63513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->width=image->columns;
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->height=image->rows;
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    width=%lu",ping_info->width);
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    height=%lu",ping_info->height);
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_matte=%u",image->matte);
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_depth=%lu",image->depth);
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    requested PNG image_depth=%lu",image->depth);
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->bit_depth=(png_byte) save_image_depth;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution);
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution);
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_UNKNOWN;
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) image->x_resolution;
64223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) image->y_resolution;
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up pHYs chunk");
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x || image->page.y)
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (png_int_32) image->page.y, 0);
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up oFFs chunk");
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_color_16
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        background;
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_depth < MAGICKCORE_QUANTUM_DEPTH)
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             maxval;
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          maxval=(1UL << image_depth)-1;
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=(png_uint_16)
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.red));
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=(png_uint_16)
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.green));
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=(png_uint_16)
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.blue));
64573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=(png_uint_16)
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*PixelIntensity(&image->background_color)));
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=image->background_color.red;
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=image->background_color.green;
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=image->background_color.blue;
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_16) PixelIntensity(&image->background_color);
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      background.index=(png_byte) background.gray;
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Setting up bKGd chunk");
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_bKGD(ping,ping_info,&background);
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->bit_depth=8;
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_depth=ping_info->bit_depth;
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: make this a function cause it's used twice, except
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             for reducing the sample depth from 8. */
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          QuantizeInfo
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantize_info;
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned long
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             number_colors,
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             save_number_colors;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image->storage_class == DirectClass) || (number_colors > 256))
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GetQuantizeInfo(&quantize_info);
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MagickFalse ? MagickTrue : MagickFalse;
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                256UL);
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) QuantizeImage(&quantize_info,image);
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors=image_colors;
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) SyncImage(image);
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    Colors quantized to %ld",number_colors);
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->valid|=PNG_INFO_tRNS;
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Set image palette.
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid|=PNG_INFO_PLTE;
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          save_number_colors=image_colors;
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (CompressColormapTransFirst(image) == MagickFalse)
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=save_number_colors;
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_color *) AcquireQuantumMemory(257,
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*palette));
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (palette == (png_color *) NULL)
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up PLTE chunk");
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) number_colors; i++)
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %3ld (%3d,%3d,%3d)",
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %5ld (%5d,%5d,%5d)",
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                i,palette[i].red,palette[i].green,palette[i].blue);
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors++;
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008)
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_colorp) RelinquishMagickMemory(palette);
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_depth=ping_info->bit_depth;
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->num_trans=0;
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_alpha=(unsigned char *) AcquireQuantumMemory(
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors,sizeof(*ping_info->trans_alpha));
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->trans == (unsigned char *) NULL)
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowWriterException(ResourceLimitError,
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) number_colors; i++)
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 ping_info->trans_alpha[i]=255;
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (y=0; y < (long) image->rows; y++)
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register const PixelPacket
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *p;
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetAuthenticPixels(image,0,y,image->columns,1,exception);
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (PixelPacket *) NULL)
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                indices=GetAuthenticIndexQueue(image);
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=0; x < (long) image->columns; x++)
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      indices[x]=(IndexPacket) (number_colors-1);
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ping_info->trans_alpha[(long) indices[x]]=(png_byte) (255-
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        ScaleQuantumToChar(p->opacity));
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (SyncAuthenticPixels(image,exception) == MagickFalse)
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) number_colors; i++)
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ping_info->trans_alpha[i] != 255)
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->num_trans=(unsigned short) (i+1);
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans == 0)
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->valid&=(~PNG_INFO_tRNS);
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (!(ping_info->valid & PNG_INFO_tRNS))
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->num_trans=0;
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans == 0)
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->trans_alpha=(unsigned char *)
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  RelinquishMagickMemory(ping_info->trans_alpha);
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Identify which colormap entry is the background color.
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=0; i < (long) MagickMax(1L*number_colors-1L,1L); i++)
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (IsPNGColorEqual(ping_info->background,image->colormap[i]))
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->background.index=(png_byte) i;
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB;
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_depth=ping_info->bit_depth;
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type=(png_byte) mng_info->write_png_colortype-1;
66383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "Selecting PNG colortype");
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type=(png_byte) ((matte == MagickTrue)?
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB;
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "Selected PNG colortype=%d",ping_info->color_type);
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->bit_depth < 8)
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->color_type == PNG_COLOR_TYPE_RGB ||
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->color_type == PNG_COLOR_TYPE_RGBA)
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->bit_depth=8;
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->bit_depth=1;
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (ping_info->bit_depth < mng_info->write_png_depth)
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->bit_depth = mng_info->write_png_depth;
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->bit_depth=1;
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           while ((int) (1 << ping_info->bit_depth) < (long) image_colors)
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->bit_depth <<= 1;
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Number of colors: %lu",image_colors);
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Tentative PNG bit depth: %d",ping_info->bit_depth);
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               old_bit_depth=ping_info->bit_depth;
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               if (ping_info->bit_depth < mng_info->write_png_depth)
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth = mng_info->write_png_depth;
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if (ping_info->bit_depth > 8)
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ping_info->bit_depth = 8;
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if (ping_info->bit_depth != old_bit_depth)
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                           "    Colors increased to %ld",image_colors);
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=ping_info->bit_depth;
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Tentative PNG color type: %d",ping_info->color_type);
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_info->type: %d",image_info->type);
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_depth: %lu",image_depth);
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    ping_info->bit_depth: %d",ping_info->bit_depth);
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (matte && (mng_info->optimize || mng_info->IsPalette))
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=(long) image->columns-1; x >= 0; x--)
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (y=0; y < (long) image->rows; y++)
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (x=(long) image->columns-1; x >= 0; x--)
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (x != 0)
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((y == (long) image->rows) && (x == (long) image->columns))
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            No transparent pixels are present.  Change 4 or 6 to 0 or 2,
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and do not set the PNG_INFO_tRNS flag in ping_info->valid.
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type&=0x03;
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 8)
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 4)
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 2)
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->bit_depth == 1)
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->valid|=PNG_INFO_tRNS;
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.red=(png_uint_16)
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(p->red) & mask);
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.green=(png_uint_16)
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(p->green) & mask);
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.blue=(png_uint_16)
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(p->blue) & mask);
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.gray=(png_uint_16)
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->trans_color.index=(png_byte)
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToChar((Quantum) (QuantumRange-p->opacity)));
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->valid & PNG_INFO_tRNS)
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (y=0; y < (long) image->rows; y++)
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
68263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (x=(long) image->columns-1; x >= 0; x--)
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (IsPNGColorEqual(ping_info->trans_color,*p) == 0)
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for multiple
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent colors.  */
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                semitransparency. */
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               else
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (IsPNGColorEqual(ping_info->trans_color,*p))
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (x != 0)
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
68573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (x != 0)
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->valid&=(~PNG_INFO_tRNS);
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ping_info->valid & PNG_INFO_tRNS)
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.red&=0xff;
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.green&=0xff;
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.blue&=0xff;
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.gray&=0xff;
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (ping_info->valid & PNG_INFO_tRNS)
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((mng_info->optimize || mng_info->IsPalette) &&
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type=PNG_COLOR_TYPE_GRAY;
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ping_info->trans_color.gray*=0x0101;
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=1 << image_depth;
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->bit_depth=16;
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->bit_depth=8;
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE)
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->bit_depth=1;
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    while ((int) (1 << ping_info->bit_depth)
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        < (long) image_colors)
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ping_info->bit_depth <<= 1;
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (mng_info->optimize && ping_info->color_type ==
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) image_colors; i++)
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth=1;
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth=2;
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   ping_info->bit_depth=4;
69383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=ping_info->bit_depth;
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned long
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               number_colors;
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors=image_colors;
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               ping_info->valid|=PNG_INFO_tRNS;
69533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
69573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->valid|=PNG_INFO_PLTE;
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 png_set_PLTE(ping,ping_info,NULL,0);
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (logging)
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "  Setting up empty PLTE chunk");
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned long
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   save_number_colors;
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->optimize)
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    save_number_colors=image_colors;
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (CompressColormapTransFirst(image) == MagickFalse)
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       ThrowWriterException(ResourceLimitError,
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                            "MemoryAllocationFailed");
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    number_colors=image_colors;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image_colors=save_number_colors;
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_color *) AcquireQuantumMemory(257,
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sizeof(*palette));
69833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (palette == (png_color *) NULL)
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) number_colors; i++)
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging)
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Setting up PLTE chunk");
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008)
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_colorp) RelinquishMagickMemory(palette);
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->bit_depth=1;
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                while ((1UL << ping_info->bit_depth) < number_colors)
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->bit_depth <<= 1;
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->num_trans=0;
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const PixelPacket
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p;
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[256];
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const IndexPacket
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *packet_indices;
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < (long) number_colors; i++)
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[i]=256;
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (y=0; y < (long) image->rows; y++)
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (const PixelPacket *) NULL)
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                packet_indices=GetVirtualIndexQueue(image);
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (x=0; x < (long) image->columns; x++)
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      IndexPacket
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        packet_index;
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      packet_index=packet_indices[x];
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      assert((unsigned long) packet_index < number_colors);
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (trans[(long) packet_index] != 256)
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (trans[(long) packet_index] != (png_byte) (255-
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             ScaleQuantumToChar(p->opacity)))
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              ping_info->color_type=(png_byte)
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                PNG_COLOR_TYPE_RGB_ALPHA;
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              break;
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      trans[(long) packet_index]=(png_byte) (255-
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        ScaleQuantumToChar(p->opacity));
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((int) ping_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->num_trans=0;
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->valid&=(~PNG_INFO_tRNS);
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->valid&=(~PNG_INFO_PLTE);
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->IsPalette=MagickFalse;
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) SyncImage(image);
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (logging)
70673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "    Cannot write image as indexed PNG, writing RGBA.");
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
70703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((ping_info->valid & PNG_INFO_tRNS))
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) number_colors; i++)
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] == 256)
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    trans[i]=255;
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] != 255)
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->num_trans=(unsigned short) (i+1);
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans == 0)
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->valid&=(~PNG_INFO_tRNS);
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (!(ping_info->valid & PNG_INFO_tRNS))
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->num_trans=0;
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ping_info->num_trans != 0)
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ping_info->trans_alpha=(unsigned char *) AcquireQuantumMemory(
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  number_colors,sizeof(*ping_info->trans_alpha));
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ping_info->trans_alpha == (unsigned char *) NULL)
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) number_colors; i++)
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ping_info->trans_alpha[i]=(png_byte) trans[i];
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Identify which colormap entry is the background color.
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) MagickMax(1L*number_colors-1L,1L); i++)
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (IsPNGColorEqual(ping_info->background,image->colormap[i]))
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->background.index=(png_byte) i;
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.red*=0x0101;
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.green*=0x0101;
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.blue*=0x0101;
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->trans_color.gray*=0x0101;
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
71233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (ping_info->bit_depth < 8 && ping_info->color_type ==
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_color_16
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           background;
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         maxval=(png_uint_16) ((1 << ping_info->bit_depth)-1);
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         background.gray=(png_uint_16)
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Setting up bKGD chunk");
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_set_bKGD(ping,ping_info,&background);
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         ping_info->trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->trans_color.gray));
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    PNG color type: %d",ping_info->color_type);
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up deflate compression");
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 99)
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression buffer size: 32768");
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
71653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
71663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      level=(int) MagickMin((long) quality/10,9);
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->filter_type=PNG_INTRAPIXEL_DIFFERENCING;
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter=PNG_ALL_FILTERS;
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((quality % 10) != 5)
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (((int) ping_info->color_type == PNG_COLOR_TYPE_GRAY) ||
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((int) ping_info->color_type == PNG_COLOR_TYPE_PALETTE) ||
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_NO_FILTERS;
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_ALL_FILTERS;
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
72253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10008) && defined(PNG_WRITE_iCCP_SUPPORTED)
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_set_sRGB(ping,ping_info,(int) (image->rendering_intent-1));
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_mng) || !(ping_info->valid & PNG_INFO_sRGB))
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->interlace_type=image_info->interlace != NoInterlace;
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ping_info->color_type = PNG_COLOR_TYPE_RGB;
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (ping_info->bit_depth < 8)
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ping_info->bit_depth=8;
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         ping_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->write_png_depth != ping_info->bit_depth) ||
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->write_png_colortype-1 != ping_info->color_type))
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->bit_depth);
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ping_info->color_type);
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_error(ping,
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && !image->matte)
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       unsigned char
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[14];
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping->mode |= PNG_HAVE_IDAT;
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth <= 8)
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png24 || (mng_info->write_png_depth == 8 &&
74043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_RGB))
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (mng_info->write_png32 || (mng_info->write_png_depth == 8 &&
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_RGB_ALPHA))
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if ((!mng_info->write_png8 ||
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY ||
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA )&&
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           ((mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image)))
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=(image_matte ? 2 : 1);
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (!mng_info->IsPalette)
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            rowbytes*=(image_matte ? 4 : 3);
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->optimize || mng_info->IsPalette) &&
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ImageIsGray(image))
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=(image_matte ? 4 : 2);
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=(image_matte ? 8 : 6);
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging)
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Allocating %lu bytes of memory for pixels",rowbytes);
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (setjmp(ping->jmpbuf))
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
74433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7453a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy      (void) UnlockSemaphoreInfo(png_semaphore);
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
74563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7457ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
7458ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
7459ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
74623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mng_info->optimize || mng_info->IsPalette ||
74663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
74683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
74703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (y=0; y < (long) image->rows; y++)
74793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
74863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < (long) image->columns; i++)
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < (long) image->columns; i++)
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
75093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
75113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (ping_info->bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (y=0; y < (long) image->rows; y++)
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
75473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
75503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
75523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
75533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
75553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
75563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
75583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
75593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
75603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
75623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (y=0; y < (long) image->rows; y++)
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
75643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
75653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
75663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
75673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
75763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
75913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((ping_info->color_type != PNG_COLOR_TYPE_GRAY) &&
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (ping_info->color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
75953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging)
75963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (y=0; y < (long) image->rows; y++)
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging)
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->color_type == PNG_COLOR_TYPE_GRAY)
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (ping_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
76163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7629b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
7630b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Writing PNG image data");
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Width: %lu",ping_info->width);
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Height: %lu",ping_info->height);
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
76413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
76443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG bit-depth written: %d",ping_info->bit_depth);
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color-type written: %d",ping_info->color_type);
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG Interlace method: %d",ping_info->interlace_type);
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER <= 10005)
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info->num_text=0;
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
76663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
76693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
76743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER > 10005)
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
76823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
76833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
76843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
76883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
76893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Work directly with ping_info struct; png_set_text before libpng version
76943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * 1.0.5a is leaky */
76953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ping_info->num_text == 0)
76963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ping_info->text=(png_text *) AcquireQuantumMemory(256,
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              sizeof(*ping_info->text));
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ping_info->text == (png_text *) NULL)
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i=ping_info->num_text++;
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (i > 255)
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ResourceLimitError,"Cannot write more than 256 PNG text chunks",
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "`%s'",image->filename);
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].key=(char *) property;
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].text=(char *) value;
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].text_length=strlen(value);
77123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->text[i].compression=
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->compression == NoCompression ||
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ping_info->text[i].text_length < 128) ? -1 : 0;
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
77173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",ping_info->text[i].key);
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
77263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
77273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
77293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
77303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->width != mng_info->page.width) ||
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (ping_info->height != mng_info->page.height))
77403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
77423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
77503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
77513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
77593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (png_uint_32) (mng_info->page.x + ping_info->width));
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (png_uint_32) (mng_info->page.y + ping_info->height));
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
77673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
77703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
77713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
77733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
77743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
77753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
77763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
77773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[0]=(char) ping_info->bit_depth;
77823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
77833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_PLTE)
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->palette=(png_colorp)
77933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        RelinquishMagickMemory(ping_info->palette);
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->valid&=(~PNG_INFO_PLTE);
77953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
77963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info->valid & PNG_INFO_tRNS)
77973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
77983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->trans_alpha=(unsigned char *) RelinquishMagickMemory(
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ping_info->trans_alpha);
78003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping_info->valid&=(~PNG_INFO_tRNS);
78013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
78033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
78053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7809a45da9d457daa1f2ce937c13ef3e1922f28b4e18cristy  (void) UnlockSemaphoreInfo(png_semaphore);
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
78113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
78153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
78253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
78313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
78363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
78583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
78643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
78663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
78673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               channel is present even if the image is fully opaque.
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               from the application programming interfaces.
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
78813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
78893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
78903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
78913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
78923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Allow all other PNG subformats to be requested via new
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "-define png:bit-depth -define png:color-type" options.
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
79173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
79223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  subsequent profiles from overwriting the preceding ones:
79233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
79513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
79523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
79653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
79753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 3 */ 4;
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0 /* this does not work */
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,PaletteMatteType);
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,PaletteType);
79883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 2 */ 3;
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorMatteType);
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorType);
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
80023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 6 */  7;
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
80083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorMatteType);
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorType);
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 1;
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 2;
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 4;
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
80263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 16;
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
80303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
80353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
80373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 1;
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 3;
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 4;
80433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 5;
80453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 7;
80473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
80503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
80553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
80583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
80603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
80613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
80673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
80683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
80763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
80793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
81003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             &image->exception);
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
81993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Successfully read jpeg_image into a blob, length=%lu.",
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (unsigned long) length);
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
82093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+4,image->columns);
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+8,image->rows);
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
82233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
82243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
82273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG width:%15lu",image->columns);
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG height:%14lu",image->rows);
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
82453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-b profiles */
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    long
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,(unsigned long) (num_bytes-4L));
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    LogPNGChunk((int) logging,mng_bKGD,(unsigned long) (num_bytes-4L));
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (image->rendering_intent-1);
83023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (PerceptualIntent-1);
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
83133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
83153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
83163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+4,(unsigned long) (100000*image->gamma+0.5));
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+4,(unsigned long) (100000*primary.x+0.5));
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+8,(unsigned long) (100000*primary.y+0.5));
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+12,(unsigned long) (100000*primary.x+0.5));
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+16,(unsigned long) (100000*primary.y+0.5));
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+20,(unsigned long) (100000*primary.x+0.5));
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+24,(unsigned long) (100000*primary.y+0.5));
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+28,(unsigned long) (100000*primary.x+0.5));
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+32,(unsigned long) (100000*primary.y+0.5));
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+4,(unsigned long)
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
83613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+8,(unsigned long)
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+4,(unsigned long)
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+8,(unsigned long)
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+4,(unsigned long) (image->x_resolution+0.5));
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              PNGLong(chunk+8,(unsigned long) (image->y_resolution+0.5));
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
83833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
83903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGsLong(chunk+4,(long) (image->page.x));
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGsLong(chunk+8,(long) (image->page.y));
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
84013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          register long
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          long
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Write IDAT chunks from blob, length=%lu.",
84273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (unsigned long) length);
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
84313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (i=8; i<(long) length; i+=len+12)
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
84363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,(unsigned long) len);
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IDAT,(unsigned long) len);
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
84483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Skipping %c%c%c%c chunk, length=%lu.",
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *(p),*(p+1),*(p+2),*(p+3),len);
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
84523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
84543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Write JDAA chunk, length=%lu.",
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (unsigned long) length);
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,(unsigned long) length);
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
84683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
84693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
84753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
84813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
84853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
84883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
84893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Created jpeg_image, %lu x %lu.",jpeg_image->columns,
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->rows);
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
85083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
85113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Successfully read jpeg_image into a blob, length=%lu.",
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (unsigned long) length);
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Write JDAT chunk, length=%lu.",
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (unsigned long) length);
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,(unsigned long) length);
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
85313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
85343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
85373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
85403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
85413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
85433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
85533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
85583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
85763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
85863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
85953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
86193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
86263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
86373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register long
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned long
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned long
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10007)
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
87243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=MagickFalse;
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=(image_info->type == OptimizeType || image_info->type ==
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      UndefinedType);
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (optimize)
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: TRUE");
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: FALSE");
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Image_info depth: %ld",image_info->depth);
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Scene: %ld",scene++);
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "      Image depth: %lu",p->depth);
87713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: %lu",p->colors);
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
87933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sometimes we get PseudoClass images whose RGB values don't match
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    the colors in the colormap.  This code syncs the RGB values.
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Image
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p;
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p->taint && p->storage_class == PseudoClass)
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(p);
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->adjoin == MagickFalse)
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_BUILD_PALETTE
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (optimize)
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Sometimes we get DirectClass images that have 256 colors or fewer.
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        This code will convert them to PseudoClass and build a colormap.
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
88183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
88203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class != PseudoClass)
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p->colors <= 256)
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p->colors=0;
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p->matte != MagickFalse)
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageType(p,PaletteMatteType);
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageType(p,PaletteType);
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
88493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
88733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
88763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
88803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
88993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
89113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
89183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 final_delay=10;
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 (void) ThrowMagickException(&image->exception,
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "input has zero delay between all frames; assuming 10 cs",
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "`%s'","");
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1UL*image->ticks_per_second/final_delay;
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+4,mng_info->page.width);
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+8,mng_info->page.height);
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,(unsigned long) length);
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_nEED,(unsigned long) length);
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "     TERM delay: %lu",
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (png_uint_32) (mng_info->ticks_per_second*
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  final_delay/MagickMax(image->ticks_per_second,1)));
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 "     TERM iterations: %lu",PNG_UINT_31_MAX);
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 "     Image iterations: %lu",image->iterations);
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (image->rendering_intent-1);
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (PerceptualIntent-1);
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+4,(unsigned long) (100000*image->gamma+0.5));
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+4,(unsigned long) (100000*primary.x+0.5));
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(unsigned long) (100000*primary.y+0.5));
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(unsigned long) (100000*primary.x+0.5));
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+16,(unsigned long) (100000*primary.y+0.5));
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+20,(unsigned long) (100000*primary.x+0.5));
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+24,(unsigned long) (100000*primary.y+0.5));
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+28,(unsigned long) (100000*primary.x+0.5));
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+32,(unsigned long) (100000*primary.y+0.5));
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+4,(unsigned long)
92053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
92063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(unsigned long)
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+4,(unsigned long)
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+8,(unsigned long)
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+4,(unsigned long) (image->x_resolution+0.5));
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 PNGLong(chunk+8,(unsigned long) (image->y_resolution+0.5));
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
92373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         unsigned long
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
92753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         for (i=0; i < (long) image->colors; i++)
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
92923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
92933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
92953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
92963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
92993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
93013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
93023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned long
93203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=0; i < (long) image->colors; i++)
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
93283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
93363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        long
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->delay=image->delay;
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
94333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* PNG_LIBPNG_VER > 95 */
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* PNG_LIBPNG_VER > 95 */
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9498