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