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