png.c revision cee9711bbc334b5677d5ec4ea1cc70340d35ee35
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N   N   GGGG                              %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P   P  NN  N  G                                  %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   N N N  G  GG                              %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N  NN  G   G                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      N   N   GGG                               %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%              Read/Write Portable Network Graphics Image Format              %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                           Glenn Randers-Pehrson                             %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                               November 1997                                 %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2116af1cbdffcc02e7239d432e5fb51734fcf9f9ffcristy%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/studio.h"
455a2ca481ab4ff6751bba842263739966e53441aacristy#include "magick/attribute.h"
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h"
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h"
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h"
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color.h"
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color-private.h"
514ccd4c0b8623aa47f1c10dd366666799e5957c3ccristy#include "magick/colormap.h"
523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/enhance.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/geometry.h"
58f2e1166e90de2dfe2e6a2aed7cd5f73640f34a7acristy#include "magick/histogram.h"
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/layer.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h"
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/profile.h"
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/property.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantize.h"
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/resource_.h"
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/semaphore.h"
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/static.h"
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/statistic.h"
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/string_.h"
80f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy#include "magick/string-private.h"
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/transform.h"
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/utility.h"
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
84286a6355c4544b794da2b6df973faad07c69e541glennrp
857ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
867ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
87faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
887ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
90991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
91faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
92faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
93faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
94faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
95286a6355c4544b794da2b6df973faad07c69e541glennrp
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
102d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_BUILD_PALETTE   /* This works as of 5.4.3. */
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SORT_PALETTE    /* This works as of 5.4.0. */
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *png_semaphore = (SemaphoreInfo *) NULL;
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
175bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
256bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
344bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
390bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
422bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
482d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   C o m p r e s s C o l o r m a p T r a n s F i r s t                       %
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  CompressColormapTransFirst compresses an image colormap removing
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  any duplicate and unused color entries and putting the transparent colors
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  first.  Returns MagickTrue on success, MagickFalse on error.
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the CompressColormapTransFirst method is:
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      unsigned int CompressColormapTransFirst(Image *image)
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
50698156a3a465a004545e39434c63052b955a74d1cglennrp%      This function updates image->colors and image->colormap.
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType CompressColormapTransFirst(Image *image)
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    remap_needed,
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    k;
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
515bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    j,
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors,
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_colors,
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *colormap;
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const IndexPacket
5255c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top_used;
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
533bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  IndexPacket
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *map,
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *opacity;
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *marker,
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_transparency;
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if colormap can be compressed.
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
55198156a3a465a004545e39434c63052b955a74d1cglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55298156a3a465a004545e39434c63052b955a74d1cglennrp           "    CompressColorMapTransFirst %s (%ld colors)",
55398156a3a465a004545e39434c63052b955a74d1cglennrp           image->filename,image->colors);
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class != PseudoClass || image->colors > 256 ||
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors < 2)
55698156a3a465a004545e39434c63052b955a74d1cglennrp    {
55798156a3a465a004545e39434c63052b955a74d1cglennrp      if (image->debug != MagickFalse)
55898156a3a465a004545e39434c63052b955a74d1cglennrp        {
55998156a3a465a004545e39434c63052b955a74d1cglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56098156a3a465a004545e39434c63052b955a74d1cglennrp               "    Could not compress colormap");
56198156a3a465a004545e39434c63052b955a74d1cglennrp          if (image->colors > 256 || image->colors == 0)
56298156a3a465a004545e39434c63052b955a74d1cglennrp            return(MagickFalse);
56398156a3a465a004545e39434c63052b955a74d1cglennrp          else
56498156a3a465a004545e39434c63052b955a74d1cglennrp            return(MagickTrue);
56598156a3a465a004545e39434c63052b955a74d1cglennrp        }
56698156a3a465a004545e39434c63052b955a74d1cglennrp    }
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) AcquireQuantumMemory(image->colors,sizeof(*marker));
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (marker == (unsigned char *) NULL)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) AcquireQuantumMemory(image->colors,sizeof(*opacity));
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (opacity == (IndexPacket *) NULL)
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Mark colors that are present.
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  number_colors=(ssize_t) image->colors;
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    marker[i]=MagickFalse;
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    opacity[i]=OpaqueOpacity;
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  top_used=0;
588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5935c6f789db7a30bad01ace12b09ad9cd471339e94cristy    indexes=GetVirtualIndexQueue(image);
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->matte != MagickFalse)
595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5975c6f789db7a30bad01ace12b09ad9cd471339e94cristy        marker[(int) indexes[x]]=MagickTrue;
5985c6f789db7a30bad01ace12b09ad9cd471339e94cristy        opacity[(int) indexes[x]]=GetOpacityPixelComponent(p);
5995c6f789db7a30bad01ace12b09ad9cd471339e94cristy        if (indexes[x] > top_used)
6005c6f789db7a30bad01ace12b09ad9cd471339e94cristy           top_used=indexes[x];
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p++;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (x=0; x < (ssize_t) image->columns; x++)
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6065c6f789db7a30bad01ace12b09ad9cd471339e94cristy        marker[(int) indexes[x]]=MagickTrue;
6075c6f789db7a30bad01ace12b09ad9cd471339e94cristy        if (indexes[x] > top_used)
6085c6f789db7a30bad01ace12b09ad9cd471339e94cristy           top_used=indexes[x];
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Mark background color, topmost occurrence if more than one.
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (i=number_colors-1; i; i--)
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsColorEqual(image->colormap+i,&image->background_color))
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          marker[i]=MagickTrue;
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Unmark duplicates.
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors-1; i++)
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            marker[j]=MagickFalse;
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Count colors that still remain.
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_transparency=MagickFalse;
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  new_number_colors=0;
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        new_number_colors++;
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (opacity[i] != OpaqueOpacity)
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          have_transparency=MagickTrue;
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!have_transparency || (marker[0] &&
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (opacity[0] == (Quantum) TransparentOpacity)))
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      && (new_number_colors == number_colors))
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        No duplicate or unused entries, and transparency-swap not needed.
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  remap_needed=MagickFalse;
662bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((ssize_t) top_used >= new_number_colors)
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     remap_needed=MagickTrue;
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Compress colormap.
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) AcquireQuantumMemory(image->colors,
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*colormap));
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (colormap == (PixelPacket *) NULL)
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Eliminate unused colormap entries.
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) AcquireQuantumMemory((size_t) number_colors,
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*map));
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (map == (IndexPacket *) NULL)
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      marker=(unsigned char *) RelinquishMagickMemory(marker);
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->filename);
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  k=0;
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    map[i]=(IndexPacket) k;
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (j=i+1; j < number_colors; j++)
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((opacity[i] == opacity[j]) &&
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (IsColorEqual(image->colormap+i,image->colormap+j)))
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               map[j]=(IndexPacket) k;
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               marker[j]=MagickFalse;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        k++;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  j=0;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; i < number_colors; i++)
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (marker[i])
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        colormap[j]=image->colormap[i];
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        j++;
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (have_transparency && (opacity[0] != (Quantum) TransparentOpacity))
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Move the first transparent color to palette entry 0.
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < number_colors; i++)
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (marker[i] && opacity[i] == (Quantum) TransparentOpacity)
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PixelPacket
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              temp_colormap;
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            temp_colormap=colormap[0];
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            colormap[0]=colormap[(int) map[i]];
732bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            colormap[(ssize_t) map[i]]=temp_colormap;
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (j=0; j < number_colors; j++)
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (map[j] == 0)
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=map[i];
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else if (map[j] == map[i])
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                map[j]=0;
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            remap_needed=MagickTrue;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  opacity=(IndexPacket *) RelinquishMagickMemory(opacity);
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  marker=(unsigned char *) RelinquishMagickMemory(marker);
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (remap_needed)
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ExceptionInfo
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *exception;
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register IndexPacket
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *pixels;
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register PixelPacket
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *q;
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Remap pixels.
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=(&image->exception);
764bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pixels=GetAuthenticIndexQueue(image);
770bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          j=(int) pixels[x];
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pixels[x]=map[j];
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < new_number_colors; i++)
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->colormap[i]=colormap[i];
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  colormap=(PixelPacket *) RelinquishMagickMemory(colormap);
782bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->colors=(size_t) new_number_colors;
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  map=(IndexPacket *) RelinquishMagickMemory(map);
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s G r a y                                                     %
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsGray(Image *image)
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
808bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
820bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsGray(image->colormap+i) == MagickFalse)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=(ssize_t) image->columns-1; x >= 0; x--)
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (IsGray(p) == MagickFalse)
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       p++;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I m a g e I s M o n o c h r o m e                                         %
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   Like IsMonochromeImage except does not change DirectClass to PseudoClass  %
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   and is more accurate.                                                     %
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType ImageIsMonochrome(Image *image)
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
861bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x,
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (i=0; i < (ssize_t) image->colors; i++)
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((IsGray(image->colormap+i) == MagickFalse) ||
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ((image->colormap[i].red != 0) &&
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (image->colormap[i].red != (Quantum) QuantumRange)))
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickTrue);
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
881bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
886bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=(ssize_t) image->columns-1; x >= 0; x--)
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->red != 0) && (p->red != (Quantum) QuantumRange))
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsGray(p) == MagickFalse)
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((p->opacity != OpaqueOpacity) &&
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (p->opacity != (Quantum) TransparentOpacity))
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
900d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1012d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1013bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void LogPNGChunk(int logging, png_bytep type, size_t length)
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing %c%c%c%c chunk, length: %lu",
1059bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      type[0],type[1],type[2],type[3],(size_t) length);
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1061d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1067d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1181bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            "Expected %lu bytes; found %lu bytes",(size_t) length,
1182bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (size_t) check);
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1210bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
1306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1343bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1345bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoFreeStruct(MngInfo *mng_info,int *have_mng_structure)
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*have_mng_structure && (mng_info != (MngInfo *) NULL))
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1353bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1391bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1393bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1394bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1411bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1413bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  pair.a=(ssize_t) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
1414bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  pair.b=(ssize_t) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1423bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic ssize_t mng_get_ssize_t(unsigned char *p)
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  return((ssize_t) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGErrorHandler(png_struct *ping,png_const_charp message)
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
1439faa852bad40107edae19405e76a299057668d795glennrp#if PNG_LIBPNG_VER < 10500
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1441faa852bad40107edae19405e76a299057668d795glennrp#else
1442faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1443faa852bad40107edae19405e76a299057668d795glennrp#endif
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGWarningHandler(png_struct *ping,png_const_charp message)
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1456cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_voidp png_IM_malloc(png_structp png_ptr,png_uint_32 size)
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_free_ptr png_IM_free(png_structp png_ptr,png_voidp ptr)
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_read_raw_profile(Image *image, const ImageInfo *image_info,
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1498bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
1529f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
1550bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
15623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
15763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
15883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
15953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
1610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
16373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1665faa852bad40107edae19405e76a299057668d795glennrp    pass,
1666faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1667faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1668faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1669faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1670faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
1671faa852bad40107edae19405e76a299057668d795glennrp    ping_num_trans;
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent_color;
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1679faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1680faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1681faa852bad40107edae19405e76a299057668d795glennrp
1682faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1683faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1684faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1685faa852bad40107edae19405e76a299057668d795glennrp
16863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1696faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1697faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1698faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
1699faa852bad40107edae19405e76a299057668d795glennrp    ping_rowbytes;
1700faa852bad40107edae19405e76a299057668d795glennrp
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
17145c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1716bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1726bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOnePNGImage()");
17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1745f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
174825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
175461b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
175561b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
175661b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
175761b4c957269727a0a2526edc2331881da8346100glennrp    {
175861b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
175961b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
176061b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
176161b4c957269727a0a2526edc2331881da8346100glennrp    }
176261b4c957269727a0a2526edc2331881da8346100glennrp#  endif
176361b4c957269727a0a2526edc2331881da8346100glennrp#endif
176461b4c957269727a0a2526edc2331881da8346100glennrp
176561b4c957269727a0a2526edc2331881da8346100glennrp
1766ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   PNGErrorHandler,PNGWarningHandler, NULL,
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
1795faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1802f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
18087b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
18097b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
18107b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
18117b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1817faa852bad40107edae19405e76a299057668d795glennrp
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1851991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1852991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1853991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1867991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1871faa852bad40107edae19405e76a299057668d795glennrp
1872faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1873faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1874faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1875faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1876faa852bad40107edae19405e76a299057668d795glennrp
1877faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1878faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1879faa852bad40107edae19405e76a299057668d795glennrp
1880faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1881faa852bad40107edae19405e76a299057668d795glennrp
1882faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1884faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1885faa852bad40107edae19405e76a299057668d795glennrp        {
1886faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1887faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1888faa852bad40107edae19405e76a299057668d795glennrp        }
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1890faa852bad40107edae19405e76a299057668d795glennrp
1891faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1893faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG width: %lu, height: %lu",
1898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        (size_t) ping_width, (size_t) 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,
20470881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
20480881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
20490881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG pHYs chunk: xres: %lu, yres: %lu, units: %d.",
2059bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (size_t) x_resolution,(size_t) 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;
2220bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2222bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) 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);
2259bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) 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);
2282bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) 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        {
2291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2294faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
2297bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) 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++;
2310bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if ((image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
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
2379bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      depth=(ssize_t) 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
2386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) 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              {
2407bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) 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))
2424bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) 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
2443bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=(ssize_t) 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)
2455bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (4*image->columns); x != 0; x--)
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
24583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2460faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2461bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) (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          {
2509cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2510cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
25117a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25127a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25137a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25177a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2536faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2542bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2545faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
25483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_read_row(ping,png_pixels+row_offset,NULL);
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25525c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
25533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=png_pixels+row_offset;
25543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2555faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2559bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2562bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2570bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2577bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 6) & 0x03;
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x03;
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 2) & 0x03;
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x03;
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2586bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
25883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
25923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2593bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p >> 4) & 0x0f;
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++) & 0x0f;
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
25993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++ >> 4) & 0x0f;
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2604faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2617bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r++=*p++;
26193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
2626bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=(Quantum) quantum;
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2637faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum=((*p++) << 8);
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum|=(*p++);
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-quantum);
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
2646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              size_t
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum;
26483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (image->colors > 256)
26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=((*p++) << 8);
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *r=0;
26533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum=(*r);
26543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum|=(*p++);
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r=quantum;
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              r++;
2657faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(*p << 8) | *(p+1);
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity*=65537L;
266146f08209f719f4adeea742c45873c2714e80cdb9cristy                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p+=2;
26633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
26663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              *r++=(*p++);
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++; /* strip low byte */
2668faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
26703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) (QuantumRange-(*p++));
26713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
26833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
268780ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
26907a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
26917a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2692cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2693cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
26947a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
26957a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
26967a287bfadeadea12e47c2376ca78a5d101687142cristy          }
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
26987a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2706b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2707b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27085c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27095c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2710aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27115c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27125c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27135c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27145c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27155c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2716aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27175c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
27183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_end(ping,ping_info);
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2721bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
27243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
27253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
27263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2728f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2735faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
27393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2745c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2746e805a647adebb9faefcbd7f9a73ca8e91870614acristy#if 1  /* balfour fix */
2747c11cf6a442f3046940608a5743a68cc891deb13eglennrp/* From imagemagick discourse server, 5 Feb 2010 */
2748c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2749c11cf6a442f3046940608a5743a68cc891deb13eglennrp    if (storage_class == PseudoClass)
2750c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2751faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2752c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2753faa852bad40107edae19405e76a299057668d795glennrp         for (x=0; x < ping_num_trans; x++)
2754c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
2755faa852bad40107edae19405e76a299057668d795glennrp            image->colormap[x].opacity = ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
2756c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2757c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2758faa852bad40107edae19405e76a299057668d795glennrp      else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2759c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
27605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         for (x=0; x < (int) image->colors; x++)
2761c11cf6a442f3046940608a5743a68cc891deb13eglennrp         {
2762c11cf6a442f3046940608a5743a68cc891deb13eglennrp            if (image->colormap[x].red == transparent_color.opacity)
2763c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
2764c11cf6a442f3046940608a5743a68cc891deb13eglennrp               image->colormap[x].opacity = (Quantum) TransparentOpacity;
2765c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
2766c11cf6a442f3046940608a5743a68cc891deb13eglennrp         }
2767c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2768d027259799c88ed5e4f12d21a5366031bfef0904cristy      (void) SyncImage(image);
2769c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2770c11cf6a442f3046940608a5743a68cc891deb13eglennrp   else
2771c11cf6a442f3046940608a5743a68cc891deb13eglennrp   {
2772c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2773bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
2774c11cf6a442f3046940608a5743a68cc891deb13eglennrp      {
2775c11cf6a442f3046940608a5743a68cc891deb13eglennrp        image->storage_class=storage_class;
2776c11cf6a442f3046940608a5743a68cc891deb13eglennrp        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2777c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (q == (PixelPacket *) NULL)
2778c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
27795c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2780c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2781bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
2782c11cf6a442f3046940608a5743a68cc891deb13eglennrp          {
2783c11cf6a442f3046940608a5743a68cc891deb13eglennrp            if (ScaleQuantumToChar(q->red) == transparent_color.red &&
2784c11cf6a442f3046940608a5743a68cc891deb13eglennrp                ScaleQuantumToChar(q->green) == transparent_color.green &&
2785c11cf6a442f3046940608a5743a68cc891deb13eglennrp                ScaleQuantumToChar(q->blue) == transparent_color.blue)
2786c11cf6a442f3046940608a5743a68cc891deb13eglennrp               q->opacity=(Quantum) TransparentOpacity;
2787c11cf6a442f3046940608a5743a68cc891deb13eglennrp            else
2788c11cf6a442f3046940608a5743a68cc891deb13eglennrp              SetOpacityPixelComponent(q,OpaqueOpacity);
2789c11cf6a442f3046940608a5743a68cc891deb13eglennrp            q++;
2790c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
2791c11cf6a442f3046940608a5743a68cc891deb13eglennrp        if (SyncAuthenticPixels(image,exception) == MagickFalse)
2792c11cf6a442f3046940608a5743a68cc891deb13eglennrp          break;
2793c11cf6a442f3046940608a5743a68cc891deb13eglennrp      }
2794c11cf6a442f3046940608a5743a68cc891deb13eglennrp   }
2795c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2796c11cf6a442f3046940608a5743a68cc891deb13eglennrp#else /* not balfour */
2797c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2798c11cf6a442f3046940608a5743a68cc891deb13eglennrp
2799bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->storage_class=storage_class;
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
28055c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (storage_class == PseudoClass)
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            IndexPacket
28103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              indexpacket;
28113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2812faa852bad40107edae19405e76a299057668d795glennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2813bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
28143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
28155c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2816faa852bad40107edae19405e76a299057668d795glennrp                if (indexpacket < ping_num_trans)
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=ScaleCharToQuantum((unsigned char)
2818bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    (255-ping_trans_alpha[(ssize_t) indexpacket]));
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2820ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
2823faa852bad40107edae19405e76a299057668d795glennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
2824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=0; x < (ssize_t) image->columns; x++)
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
28265c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexpacket=indexes[x];
2827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                q->red=image->colormap[(ssize_t) indexpacket].red;
28283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->green=q->red;
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->blue=q->red;
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (q->red == transparent_color.opacity)
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) TransparentOpacity;
28323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
2833ce70c17bb6433add2eb069515a4f3105989e0662cristy                  SetOpacityPixelComponent(q,OpaqueOpacity);
28343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
28353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
2838bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (x=(ssize_t) image->columns-1; x >= 0; x--)
28393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ScaleQuantumToChar(q->red) == transparent_color.red &&
28413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->green) == transparent_color.green &&
28423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ScaleQuantumToChar(q->blue) == transparent_color.blue)
28433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               q->opacity=(Quantum) TransparentOpacity;
28443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2845ce70c17bb6433add2eb069515a4f3105989e0662cristy              SetOpacityPixelComponent(q,OpaqueOpacity);
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
28493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
28503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2851c11cf6a442f3046940608a5743a68cc891deb13eglennrp#endif /* not balfour */
28523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
28553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->depth > 8)
28563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->depth=8;
28573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_get_text(ping,ping_info,&text,&num_text) != 0)
2859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) num_text; i++)
28603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Check for a profile */
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG text chunk");
28663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(text[i].key, "Raw profile type ",17) == 0)
28673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_read_raw_profile(image,image_info,text,(int) i);
28683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
28693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
28703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
28713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
28723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=text[i].text_length;
28743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
28753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*value));
28763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value == (char *) NULL)
28773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
28783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
28793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ResourceLimitError,"MemoryAllocationFailed","`%s'",
28803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
28833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *value='\0';
28843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ConcatenateMagickString(value,text[i].text,length+2);
28853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProperty(image,text[i].key,value);
28863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
28873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "      Keyword: %s",text[i].key);
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=DestroyString(value);
28903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
28913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
28933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
28953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
28973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
28993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
290490823213d62b0ba18557e61f1e6892c6fffd6cd4cristy            AcquireAlignedMemory(1,sizeof(MngBuffer));
29053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
29363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
2937faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
29383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
2939faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
2940faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
2941faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
2942faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
2943faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
2944faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
2945faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
2946faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
2947faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
29483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
29513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
29643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
29723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2977f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
29863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
29993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
30093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
30123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
30153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
30163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadPNGImage()");
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
303690823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
30433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
30443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
30453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
30483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
30523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
30543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
30573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
30623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
30653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
30673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
30683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
30743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
30753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
30773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
30803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
30813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
30833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
30853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
30863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
30873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
30903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
30943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
30953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
30973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
30983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
30993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
31003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
31033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
31063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
31073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
31083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
31093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
31113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
31133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
31153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
31163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
31183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
31203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
31223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
31243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
31253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
31263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
31273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
31283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
31313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
31323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
31363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
31373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3139bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
31403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
31553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
31683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
31863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
31903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter ReadOneJNGImage()");
31933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
31973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
32053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
32063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Reading JNG chunk type %c%c%c%c, length: %lu",
32433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0],type[1],type[2],type[3],length);
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
32463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
32483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3254bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
32573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
32683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
32693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3271bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3273bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
32753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
32783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
32803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
32813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
32823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
32833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
32843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
32853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
32873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3288bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  "    jng_width:      %16lu",(size_t) jng_width);
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3290bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  "    jng_width:      %16lu",(size_t) jng_height);
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
333390823213d62b0ba18557e61f1e6892c6fffd6cd4cristy        color_image_info=(ImageInfo *)AcquireAlignedMemory(1,sizeof(ImageInfo));
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
33393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
33423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
335390823213d62b0ba18557e61f1e6892c6fffd6cd4cristy              AcquireAlignedMemory(1,sizeof(ImageInfo));
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
33653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
33803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_IHDR,13L);
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk to color_image->blob
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy IDAT header and chunk data to alpha_image->blob
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3430bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            LogPNGChunk((int) logging,mng_IDAT,length);
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Copy chunk data to alpha_image->blob
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
34503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
34653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
34713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
3491bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->gamma=((float) mng_get_ssize_t(p))*0.00001;
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
34973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.white_point.x=0.00001*mng_get_ssize_t(p);
3501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.white_point.y=0.00001*mng_get_ssize_t(&p[4]);
3502bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.red_primary.x=0.00001*mng_get_ssize_t(&p[8]);
3503bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.red_primary.y=0.00001*mng_get_ssize_t(&p[12]);
3504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.green_primary.x=0.00001*mng_get_ssize_t(&p[16]);
3505bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.green_primary.y=0.00001*mng_get_ssize_t(&p[20]);
3506bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.blue_primary.x=0.00001*mng_get_ssize_t(&p[24]);
3507bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->chromaticity.blue_primary.y=0.00001*mng_get_ssize_t(&p[28]);
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rendering_intent=(RenderingIntent) (p[0]+1);
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
35213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
35253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
35333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3536bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->page.x=mng_get_ssize_t(p);
3537bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->page.y=mng_get_ssize_t(&p[4]);
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3553bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->x_resolution=(double) mng_get_ssize_t(p);
3554bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            image->y_resolution=(double) mng_get_ssize_t(&p[4]);
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
35623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* To do. */
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
36213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
3632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_IEND,0L);
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3665bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3674bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the JNG image.
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
36983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.width=jng_width;
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.height=jng_height;
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.x=mng_info->x_off[mng_info->object_id];
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
37083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->page.y=mng_info->y_off[mng_info->object_id];
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadJNGImage()");
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
37883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify JNG signature.
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
380190823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(*mng_info));
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3859bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
38733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3884bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3890bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
38943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3907bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3916bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
39173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
39323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Set image_info->type=OptimizeType (new in version 5.4.0) to get the
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    following optimizations:
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  16-bit depth is reduced to 8 if all pixels contain samples whose
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       high byte and low byte are identical.
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Opaque matte channel is removed.
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  If matte channel is present but only one transparent color is
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       present, RGB+tRNS is written instead of RGBA
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Grayscale images are reduced to 1, 2, or 4 bit depth if
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       this can be done without loss.
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    o  Palette is sorted to remove unused entries and to put a
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       transparent color first, if PNG_SORT_PALETTE is also defined.
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter ReadMNGImage()");
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
397390823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->optimize=image_info->type == OptimizeType;
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
39853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Verify MNG signature.
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize some nonzero members of the MngInfo structure.
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4002bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4003bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Reading MNG chunk type %c%c%c%c, length: %lu",
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           type[0],type[1],type[2],type[3],length);
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4063bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
40773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4102bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
4104bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
41053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  MNG width: %lu",mng_info->mng_width);
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  MNG height: %lu",mng_info->mng_height);
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
4114bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->ticks_per_second=(size_t) mng_get_ssize_t(p);
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
41213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
4125bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                simplicity=(size_t) mng_get_ssize_t(p);
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu+0+0",
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->mng_width,mng_info->mng_height);
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4156bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4174bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                final_delay=(png_uint_32) mng_get_ssize_t(&p[2]);
4175bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_iterations=(png_uint_32) mng_get_ssize_t(&p[6]);
41763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    final_delay=%ld",final_delay);
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    image->iterations=%ld",image->iterations);
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4232bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) | (p[5] << 16) |
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
4234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) | (p[9] << 16) |
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[10] << 8) | p[11]);
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "  x_off[%d]: %lu",object_id,mng_info->x_off[object_id]);
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "  y_off[%d]: %lu",object_id,mng_info->y_off[object_id]);
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global PLTE.
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
4304bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_plte_length=length/3;
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
43213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
43283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4332bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->global_trns_length=length;
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4347bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4350bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                igamma=mng_get_ssize_t(p);
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global cHRM
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
43663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4367bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_ssize_t(p);
4368bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_ssize_t(&p[4]);
4369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_ssize_t(&p[8]);
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
4371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  mng_get_ssize_t(&p[12]);
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
4373bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  mng_get_ssize_t(&p[16]);
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
4375bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  mng_get_ssize_t(&p[20]);
43763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
4377bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  mng_get_ssize_t(&p[24]);
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
4379bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  mng_get_ssize_t(&p[28]);
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_srgb_intent=(RenderingIntent) (p[0]+1);
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
43983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* To do. */
44053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
44083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
44193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
44213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
44263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Note the delay and frame clipping boundaries.
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
4436bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
4439bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        frame_delay=(1UL*image->ticks_per_second*
4453bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                            (mng_get_ssize_t(p))/mng_info->ticks_per_second);
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Framing_delay=%ld",frame_delay);
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        frame_timeout=(1UL*image->ticks_per_second*
4464bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                            (mng_get_ssize_t(p))/mng_info->ticks_per_second);
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Framing_timeout=%ld",frame_timeout);
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "    Frame_clipping: L=%ld R=%ld T=%ld B=%ld",
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              fb.left, fb.right,fb.top,fb.bottom);
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
4488bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
4490bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "   subframe_width=%lu, subframe_height=%lu",
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                subframe_width, subframe_height);
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
45113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Inserted background layer, L=%ld, R=%ld, T=%ld, B=%ld",
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->clip.left,mng_info->clip.right,
45403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->clip.top,mng_info->clip.bottom);
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
45503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
45803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read DISC or SEEK.
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4614bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              read MOVE
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
4623bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
46403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Record starting point.
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
4652bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            loop_iters=mng_get_ssize_t(&chunk[1]);
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  LOOP level %ld  has %ld iterations ",loop_level,loop_iters);
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
46623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
46873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "  ENDL: LOOP level %ld  has %ld remaining iterations ",
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level,mng_info->loop_count[loop_level]);
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
47083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
47123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
47703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
47743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
48113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
48143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
48213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
48293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
48333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
48353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
48403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
48563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
4872bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    (size_t) mng_get_ssize_t(p);
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
4874bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    (size_t) mng_get_ssize_t(&p[4]);
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
48853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
4897bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
4899bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
49223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
49273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
4963bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        image_width=(size_t) mng_get_ssize_t(p);
4964bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        image_height=(size_t) mng_get_ssize_t(&p[4]);
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
4977bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
4979bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
49873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
49933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Make a background rectangle.
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
50083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Inserted transparent background layer, W=%lud, H=%lud",
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->mng_width,mng_info->mng_height);
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
50463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
50493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Inserted background layer, L=%ld, R=%ld, T=%ld, B=%ld",
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->clip.left,mng_info->clip.right,
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->clip.top,mng_info->clip.bottom);
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
50813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
50913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
5116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
51223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
51533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-2)*(mng_info->magn_mx);
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=image->columns;
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
51823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += (image->columns-3)*(mng_info->magn_mx-1);
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-2)*(mng_info->magn_my);
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=image->rows;
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += (image->rows-3)*(mng_info->magn_my-1);
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5212bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5216bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
52213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Allocate next image structure.
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
52483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5261bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
5265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
52673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
52923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Magnify the rows to %lu",large_image->rows);
5302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
53143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
5317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
5321bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5323bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5324bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
5325bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5328bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
5332bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
53343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5343bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
5349bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
53515c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      /* TO DO: get color as function of indexes[x] */
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5370bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5372bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5373bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5375bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5376bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5379bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5382bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5402bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5403bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Magnify the columns to %lu",image->columns);
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5435bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
5443bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5444bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5446bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5447bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
5448bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5450bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
5452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5455bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
5472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
5475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
5478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
54793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
5481bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
5504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 32)
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
5522bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
5525bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
55293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
55343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
55613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
5581bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
5582bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
55943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 16)  /* TO DO: treat Q:32 */
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* Determine if bit depth can be reduced from 16 to 8.
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * Note that the method GetImageDepth doesn't check background
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * and doesn't handle PseudoClass specially.  Also it uses
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * multiplication and division by 257 instead of shifting, so
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     * might be slower.
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->optimize && image->depth == 16)
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        int
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ok_to_reduce;
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const PixelPacket
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *p;
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5636bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ok_to_reduce=(((((size_t) image->background_color.red >> 8) &
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     0xff)
5638bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.red & 0xff)) &&
5639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.green >> 8) & 0xff)
5640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.green & 0xff)) &&
5641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           ((((size_t) image->background_color.blue >> 8) & 0xff)
5642bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          == ((size_t) image->background_color.blue & 0xff)));
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce && image->storage_class == PseudoClass)
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int indx;
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5647bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (indx=0; indx < (ssize_t) image->colors; indx++)
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5649bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ok_to_reduce=(((((size_t) image->colormap[indx].red >>
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    8) & 0xff)
5651bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].red & 0xff)) &&
5652bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].green >> 8) & 0xff)
5653bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].green & 0xff)) &&
5654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) image->colormap[indx].blue >> 8) & 0xff)
5655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  == ((size_t) image->colormap[indx].blue & 0xff)));
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == MagickFalse)
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((ok_to_reduce != MagickFalse) &&
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->storage_class != PseudoClass))
56623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5663bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              y;
56653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5666bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              x;
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5669bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (y=0; y < (ssize_t) image->rows; y++)
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p == (const PixelPacket *) NULL)
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5674bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
56753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ok_to_reduce=((
5677bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->red >> 8) & 0xff) ==
5678bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->red & 0xff)) &&
5679bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->green >> 8) & 0xff) ==
5680bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->green & 0xff)) &&
5681bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((((size_t) p->blue >> 8) & 0xff) ==
5682bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->blue & 0xff)) &&
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (((!image->matte ||
5684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  (((size_t) p->opacity >> 8) & 0xff) ==
5685bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  ((size_t) p->opacity & 0xff)))));
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (ok_to_reduce == 0)
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (x != 0)
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (ok_to_reduce)
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->depth=8;
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Reducing PNG bit depth to 8 without loss of info");
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
5707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
57643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
57693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
58113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  image->delay=%lu, final_delay=%lu",image->delay,final_delay);
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
58293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    scene 0 delay=%lu",image->delay);
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
58393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    scene %d delay=%lu",++scene,image->delay);
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5853bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
58703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
58723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
58963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
58993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
59013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    scene 0 delay=%lu dispose=%d",image->delay,(int) image->dispose);
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=GetNextImageInList(image);
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    scene %d delay=%lu dispose=%d",++scene,
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay,(int) image->dispose);
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
591825c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
593125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5954bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5957bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
59643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
59743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
59803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
59873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
60143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
60563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
607918b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
608018b17443128598500357da7bff2f01683cf32890cristy  png_semaphore=AllocateSemaphoreInfo();
608118b17443128598500357da7bff2f01683cf32890cristy#endif
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
61123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6113514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy  if (png_semaphore != (SemaphoreInfo *) NULL)
6114514e9e77a37d27ed811aca06ea6c300bc06cc1f2cristy    DestroySemaphoreInfo(&png_semaphore);
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
611925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Fix problem with palette sorting (when PNG_SORT_PALETTE is enabled,
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    some GIF animations don't convert properly)
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
61733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
61753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
61913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristypng_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
61993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
62033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) printf("writing raw profile: type=%s, length=%lu\n",
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (char *) profile_type, length);
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6247bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy     (png_size_t) (dp-text[0].text),"%8lu ",(size_t) length);
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
6249bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
62503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
62653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
62683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType png_write_chunk_from_profile(Image *image,
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const char *string, int logging)
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; ){
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
62893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *png_profile;
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (LocaleNCompare(name,string,11) == 0) {
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Found %s profile",name);
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=CloneStringInfo(profile);
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data=GetStringInfoDatum(png_profile),
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       length=(png_uint_32) GetStringInfoLength(png_profile);
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[4]=data[3];
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[3]=data[2];
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[2]=data[1];
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       data[1]=data[0];
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,length-5);  /* data length */
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,length-1,data+1);
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
63063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_profile=DestroyStringInfo(png_profile);
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one PNG image */
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
63203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
63253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_matte,
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6333cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6334cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
63355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_bytep
63365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ping_trans_alpha;
63375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
63383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     palette;
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
63425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
63435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
63445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
63493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
63525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
63535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
63545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6355bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
63573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
63655c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6367bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *png_pixels;
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte;
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
63795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_bit_depth,
63805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
63815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
63825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
63835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
63845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
63855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_colors,
63885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
63895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6391bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
63923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
63953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOnePNGImage()");
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6400f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(png_semaphore);
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
64045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=0,
64055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
64065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
64075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
64085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
64095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
64105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
64125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
64135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
64145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
64155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
64165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
64185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
64195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
64205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
64215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
64225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_alpha = NULL;
64235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6424ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
64253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_colors=image->colors;
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=image->depth;
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_matte=image->matte;
64283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->IsPalette=image->storage_class == PseudoClass &&
6432057310ded72df25c84f1ad647129a95c1f1753e3cristy            image_colors <= 256 && !IsOpaqueImage(image,&image->exception);
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->optimize=image_info->type == OptimizeType;
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler,(void *) NULL,
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (png_malloc_ptr) png_IM_malloc,(png_free_ptr) png_IM_free);
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGErrorHandler,PNGWarningHandler);
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
64493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) NULL;
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
64653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6468f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
64855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_width=image->columns;
64865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_height=image->rows;
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
64883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        "    width=%lu",(size_t) ping_width);
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6503bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        "    height=%lu",(size_t) ping_height);
65043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_matte=%u",image->matte);
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_depth=%lu",image->depth);
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    requested PNG image_depth=%lu",image->depth);
65103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
65125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
65183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unit_type;
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        x_resolution,
65223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        y_resolution;
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution/2.54);
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution/2.54);
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_METER;
65333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) (100.0*image->x_resolution);
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) (100.0*image->y_resolution);
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unit_type=PNG_RESOLUTION_UNKNOWN;
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          x_resolution=(png_uint_32) image->x_resolution;
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          y_resolution=(png_uint_32) image->y_resolution;
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_pHYs(ping,ping_info,x_resolution,y_resolution,unit_type);
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up pHYs chunk");
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x || image->page.y)
65503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (png_int_32) image->page.y, 0);
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "    Setting up oFFs chunk");
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && (!mng_info->adjoin || !mng_info->equal_backgrounds))
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_color_16
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        background;
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_depth < MAGICKCORE_QUANTUM_DEPTH)
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
6565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             maxval;
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          maxval=(1UL << image_depth)-1;
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=(png_uint_16)
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.red));
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=(png_uint_16)
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.green));
65733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=(png_uint_16)
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*image->background_color.blue));
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=(png_uint_16)
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (QuantumScale*(maxval*PixelIntensity(&image->background_color)));
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.red=image->background_color.red;
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.green=image->background_color.green;
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.blue=image->background_color.blue;
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          background.gray=
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_16) PixelIntensity(&image->background_color);
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      background.index=(png_byte) background.gray;
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Setting up bKGd chunk");
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_bKGD(ping,ping_info,&background);
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
65943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
65973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65995af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
66005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_bit_depth=8;
66015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
66023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: make this a function cause it's used twice, except
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             for reducing the sample depth from 8. */
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          QuantizeInfo
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            quantize_info;
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             number_colors,
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             save_number_colors;
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          number_colors=image_colors;
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image->storage_class == DirectClass) || (number_colors > 256))
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              GetQuantizeInfo(&quantize_info);
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.dither=IsPaletteImage(image,&image->exception) ==
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MagickFalse ? MagickTrue : MagickFalse;
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantize_info.number_colors= (matte != MagickFalse ? 255UL :
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                256UL);
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) QuantizeImage(&quantize_info,image);
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors=image_colors;
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) SyncImage(image);
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    Colors quantized to %ld",number_colors);
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
66295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Set image palette.
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
66335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          save_number_colors=image_colors;
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (CompressColormapTransFirst(image) == MagickFalse)
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
663898156a3a465a004545e39434c63052b955a74d1cglennrp          number_colors=image->colors;
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=save_number_colors;
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_color *) AcquireQuantumMemory(257,
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            sizeof(*palette));
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (palette == (png_color *) NULL)
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
664798156a3a465a004545e39434c63052b955a74d1cglennrp                "  Setting up PLTE chunk with %d colors",
664898156a3a465a004545e39434c63052b955a74d1cglennrp                (int) number_colors);
6649bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) number_colors; i++)
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if MAGICKCORE_QUANTUM_DEPTH == 8
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %3ld (%3d,%3d,%3d)",
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    %5ld (%5d,%5d,%5d)",
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                i,palette[i].red,palette[i].green,palette[i].blue);
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (matte)
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              number_colors++;
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].red=ScaleQuantumToChar((Quantum) QuantumRange);
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].green=ScaleQuantumToChar((Quantum) QuantumRange);
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              palette[i].blue=ScaleQuantumToChar((Quantum) QuantumRange);
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_PLTE(ping,ping_info,palette,(int) number_colors);
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          palette=(png_colorp) RelinquishMagickMemory(palette);
66735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            image_depth=ping_bit_depth;
66745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              int
66815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                trans_alpha[256];
66825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
6687bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
66885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 trans_alpha[i]=255;
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
6690bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register const PixelPacket
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *p;
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetAuthenticPixels(image,0,y,image->columns,1,exception);
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (PixelPacket *) NULL)
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
66985c6f789db7a30bad01ace12b09ad9cd471339e94cristy                indexes=GetAuthenticIndexQueue(image);
6699bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
67035c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      indexes[x]=(IndexPacket) (number_colors-1);
6704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans_alpha[(ssize_t) indexes[x]]=(png_byte) (255-
6705ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (SyncAuthenticPixels(image,exception) == MagickFalse)
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
6712bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
67135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if (trans_alpha[i] != 255)
67145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=(unsigned short) (i+1);
67155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
67175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                 png_set_invalid(ping, ping_info, PNG_INFO_tRNS);
67185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping, ping_info, PNG_INFO_tRNS))
67195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
67205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
67215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                {
67225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  for (i=0; i<256; i++)
67235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                     ping_trans_alpha[i]=(png_byte) trans_alpha[i];
67245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                }
67255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
67265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (void) png_set_tRNS(ping, ping_info,
67275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  ping_trans_alpha,
67285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  ping_num_trans,
67295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                                  &ping_trans_color);
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Identify which colormap entry is the background color.
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
6734bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
67355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (IsPNGColorEqual(ping_background,image->colormap[i]))
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
67375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_background.index=(png_byte) i;
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_matte != MagickFalse)
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* TO DO: reduce to binary transparency */
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
67475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
67525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
67605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
67615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "Selecting PNG colortype");
67695af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) ((matte == MagickTrue)?
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorType)
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if(image_info->type == TrueColorMatteType)
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == GrayscaleType) &&
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_matte == MagickFalse && ImageIsGray(image))
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
67873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((image_info->type == UndefinedType ||
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image_info->type == OptimizeType ||
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_info->type == GrayscaleMatteType) &&
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte == MagickTrue && ImageIsGray(image))
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         "Selected PNG colortype=%d",ping_color_type);
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
68045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
68055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB ||
68065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
68075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=8;
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->matte == MagickFalse && image->colors < 256)
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (ImageIsMonochrome(image))
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
68165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth=1;
68175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (ping_bit_depth < (int)mng_info->write_png_depth)
68185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth = mng_info->write_png_depth;
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
6825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           while ((int) (1 << ping_bit_depth) < (ssize_t) image_colors)
68265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Number of colors: %lu",image_colors);
68323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                "    Tentative PNG bit depth: %d",ping_bit_depth);
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (mng_info->write_png_depth)
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             {
68375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               old_bit_depth=ping_bit_depth;
68385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               if (ping_bit_depth < (int)mng_info->write_png_depth)
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 {
68405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth = mng_info->write_png_depth;
68415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth > 8)
68425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth = 8;
68435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   if (ping_bit_depth != (int) old_bit_depth)
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (logging != MagickFalse)
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                           "    Colors increased to %ld",image_colors);
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 }
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
68513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    Tentative PNG color type: %d",ping_color_type);
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_info->type: %d",image_info->type);
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    image_depth: %lu",image_depth);
68623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    ping_bit_depth: %d",ping_bit_depth);
68643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (matte && (mng_info->optimize || mng_info->IsPalette))
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=GetVirtualPixels(image,0,0,image->columns,1,&image->exception);
68725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
6873bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (IsGray(p) == MagickFalse)
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
68825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
68833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if there is any transparent color.
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
6891bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p == (const PixelPacket *) NULL)
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
6896bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=(ssize_t) image->columns-1; x >= 0; x--)
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p->opacity != OpaqueOpacity)
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (x != 0)
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
6905bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if ((y == (ssize_t) image->rows) && (x == (ssize_t) image->columns))
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
69085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            No transparent pixels are present.  Change 4 or 6 to 0 or 2.
69093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_matte=MagickFalse;
69115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type&=0x03;
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned int
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mask;
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mask=0xffff;
69195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 8)
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x00ff;
69215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 4)
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x000f;
69235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 2)
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0003;
69255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_bit_depth == 1)
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mask=0x0001;
69275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.red=(png_uint_16)
6928ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetRedPixelComponent(p)) & mask);
69295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.green=(png_uint_16)
6930ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetGreenPixelComponent(p)) & mask);
69315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.blue=(png_uint_16)
6932ce70c17bb6433add2eb069515a4f3105989e0662cristy            (ScaleQuantumToShort(GetBluePixelComponent(p)) & mask);
69335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.gray=(png_uint_16)
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (ScaleQuantumToShort(PixelIntensityToQuantum(p)) & mask);
69355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_trans_color.index=(png_byte)
693646f08209f719f4adeea742c45873c2714e80cdb9cristy            (ScaleQuantumToChar((Quantum) (GetAlphaPixelComponent(p))));
69375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (void) png_set_tRNS(ping, ping_info, NULL, 0,
69385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             &ping_trans_color);
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine if there is one and only one transparent color
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            and if so if it is fully transparent.
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
6946bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
69483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               &image->exception);
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            x=0;
69513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
6953bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
69543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p->opacity != OpaqueOpacity)
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p) == 0)
69583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for multiple
69603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent colors.  */
69613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != (Quantum) TransparentOpacity)
69633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
69643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     break;  /* Can't use RGB + tRNS for
69653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                semitransparency. */
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               else
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
69705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  if (IsPNGColorEqual(ping_trans_color,*p))
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break; /* Can't use RGB + tRNS when another pixel
69723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                having the same RGB samples is
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                transparent. */
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p++;
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (x != 0)
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
69803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (x != 0)
69815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
69855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
69863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
69885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
69895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
69905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
69915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
69965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((mng_info->optimize || mng_info->IsPalette) &&
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ImageIsGray(image) && (!image_matte || image_depth >= 8))
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
70035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
70085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray*=0x0101;
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_colors == 0 || image_colors-1 > MaxColormapSize)
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_colors=1 << image_depth;
70143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
70155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
70195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
70235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
70245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    while ((int) (1 << ping_bit_depth)
7025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
70265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (mng_info->optimize && ping_color_type ==
70303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
70363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
70443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
70483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
70555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth=1;
70563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
70575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth=2;
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
70595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                   ping_bit_depth=4;
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
70625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
70643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7067bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
706817a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
706917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
707017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
707117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
70763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
70775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->have_write_global_plte && !matte)
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 png_set_PLTE(ping,ping_info,NULL,0);
70813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (logging)
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "  Setting up empty PLTE chunk");
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
70863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SORT_PALETTE)
7088bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
70893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   save_number_colors;
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->optimize)
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    save_number_colors=image_colors;
70943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (CompressColormapTransFirst(image) == MagickFalse)
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       ThrowWriterException(ResourceLimitError,
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                            "MemoryAllocationFailed");
709798156a3a465a004545e39434c63052b955a74d1cglennrp                    number_colors=image->colors;
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image_colors=save_number_colors;
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_color *) AcquireQuantumMemory(257,
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  sizeof(*palette));
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (palette == (png_color *) NULL)
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
7106bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
71093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging)
71133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
711498156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
711598156a3a465a004545e39434c63052b955a74d1cglennrp                    (int) number_colors);
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_set_PLTE(ping,ping_info,palette,(int) number_colors);
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                palette=(png_colorp) RelinquishMagickMemory(palette);
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
71203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (!mng_info->write_png_depth)
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
71235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                while ((1UL << ping_bit_depth) < number_colors)
71245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (matte)
71283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ExceptionInfo
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *exception;
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const PixelPacket
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                *p;
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
71363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[256];
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              register const IndexPacket
71395c6f789db7a30bad01ace12b09ad9cd471339e94cristy                *packet_indexes;
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Identify which colormap entry is transparent.
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              assert(number_colors <= 256);
7145bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) number_colors; i++)
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                trans[i]=256;
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception=(&image->exception);
7148bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (y=0; y < (ssize_t) image->rows; y++)
71493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p=GetVirtualPixels(image,0,y,image->columns,1,exception);
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p == (const PixelPacket *) NULL)
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
71535c6f789db7a30bad01ace12b09ad9cd471339e94cristy                packet_indexes=GetVirtualIndexQueue(image);
7154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (x=0; x < (ssize_t) image->columns; x++)
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (p->opacity != OpaqueOpacity)
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      IndexPacket
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        packet_index;
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71615c6f789db7a30bad01ace12b09ad9cd471339e94cristy                      packet_index=packet_indexes[x];
7162bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      assert((size_t) packet_index < number_colors);
7163bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      if (trans[(ssize_t) packet_index] != 256)
71643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
7165bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                          if (trans[(ssize_t) packet_index] != (png_byte) (255-
7166ce70c17bb6433add2eb069515a4f3105989e0662cristy                             ScaleQuantumToChar(GetOpacityPixelComponent(p))))
71673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
71685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                              ping_color_type=(png_byte)
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                PNG_COLOR_TYPE_RGB_ALPHA;
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              break;
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
7173bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      trans[(ssize_t) packet_index]=(png_byte) (255-
7174ce70c17bb6433add2eb069515a4f3105989e0662cristy                        ScaleQuantumToChar(GetOpacityPixelComponent(p)));
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71805af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_num_trans=0;
71815af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
71825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  png_set_invalid(ping,ping_info,PNG_INFO_PLTE);
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->IsPalette=MagickFalse;
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) SyncImage(image);
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (logging)
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent, GetMagickModule(),
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      "    Cannot write image as indexed PNG, writing RGBA.");
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
71915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
7193bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] == 256)
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    trans[i]=255;
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (trans[i] != 255)
71985af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_num_trans=(unsigned short) (i+1);
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
72003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72015af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans == 0)
72025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
72035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
72045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_num_trans=0;
72055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              if (ping_num_trans != 0)
72063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
72075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_trans_alpha=(unsigned char *) AcquireQuantumMemory(
72085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  number_colors,sizeof(*ping_trans_alpha));
72095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                if (ping_trans_alpha == (unsigned char *) NULL)
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ThrowWriterException(ResourceLimitError,
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MemoryAllocationFailed");
7212bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
72135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_trans_alpha[i]=(png_byte) trans[i];
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
72255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
72265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
72275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
72285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
72343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
72355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_color_16
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           background;
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         maxval=(png_uint_16) ((1 << ping_bit_depth)-1);
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         background.gray=(png_uint_16)
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "  Setting up bKGD chunk");
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_set_bKGD(ping,ping_info,&background);
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
72565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
725817a1485544c62993fc7a94e343c87fed5f3e6407glennrp
725917a1485544c62993fc7a94e343c87fed5f3e6407glennrp    if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
726017a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
726117a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
726217a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
726317a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
726417a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7265bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        size_t
726617a1485544c62993fc7a94e343c87fed5f3e6407glennrp           number_colors;
726717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
726817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
726917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
7270bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
727117a1485544c62993fc7a94e343c87fed5f3e6407glennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
727217a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
727317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
727417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
727517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
727617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        if (logging)
727717a1485544c62993fc7a94e343c87fed5f3e6407glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
727817a1485544c62993fc7a94e343c87fed5f3e6407glennrp            "  Setting up bKGD chunk with index=%d",(int) i);
727917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
728017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        png_set_bKGD(ping,ping_info,&ping_background);
728117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
728217a1485544c62993fc7a94e343c87fed5f3e6407glennrp
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up deflate compression");
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression buffer size: 32768");
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7307bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
73123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
73315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
73333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
73343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
73373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter=PNG_ALL_FILTERS;
73443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((quality % 10) != 5)
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
73485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
73495af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
73513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_NO_FILTERS;
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          base_filter=PNG_ALL_FILTERS;
73543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
73603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (StringInfo *) NULL)
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
73725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((LocaleCompare(name,"ICC") == 0) ||
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (LocaleCompare(name,"ICM") == 0))
73753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_iCCP(ping,ping_info,(const png_charp) name,0,(png_charp)
73763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetStringInfoDatum(profile),
73773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     (png_uint_32) GetStringInfoLength(profile));
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
73793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_raw_profile(image_info,ping,ping_info,(unsigned char *)
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            name,(unsigned char *) name,GetStringInfoDatum(profile),
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (png_uint_32) GetStringInfoLength(profile));
73833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
73853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
73863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Setting up text chunk with %s profile",name);
73873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name=GetNextImageProfile(image);
73883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
73893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
73913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
73923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
73933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
73943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
73953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
73963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Note image rendering intent.
73973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
73983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
73993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Setting up sRGB chunk");
74013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_set_sRGB(ping,ping_info,(int) (image->rendering_intent-1));
74023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_gAMA(ping,ping_info,0.45455);
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
74113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
74123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
74143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
74163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
74173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
74183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_chrm == 0) &&
74193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
74203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image chromaticity.
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PrimaryInfo
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             bp,
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             gp,
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             rp,
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             wp;
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           wp=image->chromaticity.white_point;
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           rp=image->chromaticity.red_primary;
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           gp=image->chromaticity.green_primary;
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           bp=image->chromaticity.blue_primary;
74353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           if (logging != MagickFalse)
74373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "  Setting up cHRM chunk");
74393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
74403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               bp.x,bp.y);
74413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
74443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
74463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_colortype)
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
74533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
74543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
74555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
74565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
74575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
74613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (ImageIsGray(image) == MagickFalse)
74625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
74633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->write_png_depth &&
74665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
74673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
74685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
7469991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
74705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0))))
74713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
74733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
74743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
74753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
74763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
74783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
74795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
74803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
74813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
74823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
74833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
74843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
74853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
74865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
74873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
74883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
74893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_error(ping,
74903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
74913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
74923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_matte && !image->matte)
74943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
74953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
74963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
7498b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
7499b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7500b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
75013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
75063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
75085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
75095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
75105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
75115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
75133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
75143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-b",(int) logging);
75153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
75163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
75173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-m",(int) logging);
75183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width || image->page.height)
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       unsigned char
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[14];
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
75263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
75273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
75283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
75293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
75303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
75313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
75323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
75353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
75363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
75373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ping->mode |= PNG_HAVE_IDAT;
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
75393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
75423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
75433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
75443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
75453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
7546b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
7547b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
75487202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7550b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
75513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
7552b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7553b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
7554b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
7555b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7556b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
75573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
7558b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
7559b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
7560b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
75613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7562b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (logging)
75633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
7564b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7565b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
7566b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7567b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "    Allocating %lu bytes of memory for pixels",rowbytes);
75683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
75693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
75703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*png_pixels));
75713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_pixels == (unsigned char *) NULL)
75723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
75733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
75743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
75753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
75765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
75773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
75783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
75793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
75803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
75813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
75823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
75833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
75843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
75863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
75873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
75883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (png_pixels != (unsigned char *) NULL)
75893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
75903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7591f84a193d5f435588cd78d521fff3f1f852e227f8cristy      UnlockSemaphoreInfo(png_semaphore);
75923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
75943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7595ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
7596ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
7597ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
75983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
75993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
76003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
76013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
76023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      !mng_info->write_png32) &&
76033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (mng_info->optimize || mng_info->IsPalette ||
76043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
76053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      !image_matte && ImageIsMonochrome(image))
76063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
76083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
76093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
76113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
76123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
76133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
76143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
76153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
7616bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
76173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
76193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
76203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
76213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
76223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
76253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
76263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
76273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
76283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
76293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
7630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
76313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     *(png_pixels+i)=(unsigned char) (*(png_pixels+i)
76323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
76333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
76343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
76363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RedQuantum,png_pixels,&image->exception);
76393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
7641bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
76423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               *(png_pixels+i)=(unsigned char) ((*(png_pixels+i) > 127) ?
76433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
7644b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7645b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7646b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
76473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
76483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
76503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
76513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
76523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
76533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
76543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
76553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
76563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
76573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
76583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
76593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
76603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
76613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
76623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
76633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
76643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
76653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image_matte ||
76665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
76673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (mng_info->optimize || mng_info->IsPalette) && ImageIsGray(image))
76683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
7669bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
76703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
76713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
76723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
76733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
76745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
76753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
76763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->IsPalette)
76773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,GrayQuantum,png_pixels,&image->exception);
76793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
76803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  quantum_info,RedQuantum,png_pixels,&image->exception);
7682b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7683b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7684b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                     "    Writing GRAY PNG pixels (2)");
76853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
76863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else /* PNG_COLOR_TYPE_GRAY_ALPHA */
76873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
7688b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              if (logging && y == 0)
7689b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7690b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (2)");
76913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
76923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
76933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7694b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          if (logging && y == 0)
7695b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7696b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (2)");
76973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_write_row(ping,png_pixels);
76983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
76993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
77003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
77023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
77033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
77063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
77073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
77083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
77093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_depth > 8) || (mng_info->write_png24 ||
77103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
77113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette)))
7712bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
77133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
77163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
77183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
77193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->storage_class == DirectClass)
77203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,RedQuantum,png_pixels,&image->exception);
77223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
77233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    quantum_info,GrayQuantum,png_pixels,&image->exception);
77253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
77265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7727b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
7728b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
7729b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
7730b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                if (logging && y == 0)
7731b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7732b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "    Writing GRAY_ALPHA PNG pixels (3)");
7733b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
77343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else if (image_matte != MagickFalse)
77353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBAQuantum,png_pixels,&image->exception);
77373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
77383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,RGBQuantum,png_pixels,&image->exception);
7740b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            if (logging && y == 0)
7741b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7742b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "    Writing row of pixels (3)");
77433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
77443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
77463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /* not ((image_depth > 8) || (mng_info->write_png24 ||
77473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->write_png32 ||
77483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (!mng_info->write_png8 && !mng_info->IsPalette))) */
77493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
77505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
77515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
77523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
77533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging)
77543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
77563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              quantum_info->depth=8;
77573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_depth=8;
77583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
7759bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
77603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging)
77623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
77633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
77643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
77653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
77663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
77683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,GrayQuantum,png_pixels,&image->exception);
77705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7771b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
777207cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp                if (logging && y == 0)
7773b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7774b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                       "  Writing GRAY_ALPHA PNG pixels (4)");
7775b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
7776b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  quantum_info,GrayAlphaQuantum,png_pixels,&image->exception);
7777b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
77783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
77793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
77803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                quantum_info,IndexQuantum,png_pixels,&image->exception);
778107cd77aff3a2230f1ba3fc97f24f585b3682ff1fglennrp            if (logging && y == 0)
7782b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7783b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  "  Writing row of pixels (4)");
77843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_write_row(ping,png_pixels);
77853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
77873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
77883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
77893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
77903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
77913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
77923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
77933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
77943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7795b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
7796b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
77973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
77983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
77993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7801b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
78023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        "    Width: %lu",(size_t) ping_width);
78043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7805bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        "    Height: %lu",(size_t) ping_height);
78063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
78073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
78103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
78133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
78143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
78173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
78203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
78223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
78233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
78243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate text chunks.
78253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
78263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImagePropertyIterator(image);
78273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  property=GetNextImageProperty(image);
78283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (property != (const char *) NULL)
78293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
78303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_textp
78313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      text;
78323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value=GetImageProperty(image,property);
78343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (value != (const char *) NULL)
78353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
78363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
78373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].key=(char *) property;
78383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text=(char *) value;
78393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].text_length=strlen(value);
78403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        text[0].compression=image_info->compression == NoCompression ||
78413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image_info->compression == UndefinedCompression &&
78423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          text[0].text_length < 128) ? -1 : 0;
78433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
78443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
78453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up text chunk");
78473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    keyword: %s",text[0].key);
78493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
78503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_text(ping,ping_info,text,1);
78513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_free(ping,text);
78523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
78533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    property=GetNextImageProperty(image);
78543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
78553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
78573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"PNG-chunk-e",(int) logging);
78583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
78603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
78613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
78623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
78633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
78643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
78653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
78665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
78675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
78683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
78693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
78703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
78713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
78723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
78733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
78743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
78753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
78763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
78773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_FRAM,27L);
78783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
78793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
78803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
78813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
78823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
78833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
78843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
78853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
78863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
78873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
78885af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
78893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
78903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
78915af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
78923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
78933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
78943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
78953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
78963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
78973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
78983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
78993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
79003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
79013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
79023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) ThrowMagickException(&image->exception,GetMagickModule(),
79033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
79043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       "`%s'",image->filename);
79053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image_depth=save_image_depth;
79063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Save depth actually written */
79083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  s[0]=(char) ping_bit_depth;
79103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  s[1]='\0';
79113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProperty(image,"png:bit-depth-written",s);
79133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
79153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
79163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
79175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
79183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
79193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_pixels=(unsigned char *) RelinquishMagickMemory(png_pixels);
79213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7923f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(png_semaphore);
79243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
79253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
79273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
79293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
79303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
79313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
79323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
79333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
79343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
79363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
79373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
79383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
79393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
79403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
79413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
79423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
79453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
79463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
79483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
79503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
79523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
79543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
79563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
79583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
79603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
79623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
79643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
79653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
79663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG8:    An 8-bit indexed PNG datastream is written.  If transparency
79683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
79693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
79703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparent).  The pixels contain 8-bit indices even if
79713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               they could be represented with 1, 2, or 4 bits. Note: grayscale
79723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
79733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               PNG grayscale type might be slightly more efficient.
79743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
79763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
79773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               one of the colors as transparent.
79783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
79803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
79813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
79823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               channel is present even if the image is fully opaque.
79833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
79853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
79863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
79873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               from the application programming interfaces.
79883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
79903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
79923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
79933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
79953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
79963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
79973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
79983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
79993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
80003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
80013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
80033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
80043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  If the image cannot be written without loss in the requested PNG8, PNG24,
80063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or PNG32 format or with the requested bit-depth and color-type without loss,
80073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  a PNG file will not be written, and the encoder will return MagickFalse.
80083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
80093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
80103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
80113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  transparency prior to attempting to write the image in a format that
80123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is subject to depth, color, or transparency limitations.
80133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Enforce the previous paragraph.
80153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  TODO: Allow all other PNG subformats to be requested via new
80173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "-define png:bit-depth -define png:color-type" options.
80183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
80203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
80213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
80223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
80243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
80253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
80263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
80273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
80293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
80313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
80323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
80343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
80353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
80363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  subsequent profiles from overwriting the preceding ones:
80373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x01:file01 -profile PNG-chunk-x02:file02
80393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
80403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
80423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
80433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
80443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
80453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
80463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
80473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
80493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
80503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
80523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
80533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
80553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
80563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
80583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
80593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
80623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
80653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
80663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
80673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
80683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WritePNGImage()");
80693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
80703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
80713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
80723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
80743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
807690823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
80773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
80783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
80793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
80853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
80873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
80903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
80913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 3 */ 4;
80953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
80973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0 /* this does not work */
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,PaletteMatteType);
81003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,PaletteType);
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
81033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
81073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 2 */ 3;
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorMatteType);
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorType);
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = /* 6 */  7;
81213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
81223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->depth = 8;
81233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->matte == MagickTrue)
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorMatteType);
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageType(image,TrueColorType);
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(image);
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
81323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 1;
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 2;
81373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 4;
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
81403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 8;
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
81423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_depth = 16;
81433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
81483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
81513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 1;
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 3;
81553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 4;
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
81583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 5;
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->write_png_colortype = 7;
81613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         "png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOnePNGImage(mng_info,image_info,image);
81673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
81693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
81713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
81733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
81753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
81773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
81793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
81813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
81823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
81863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
81873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
81923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
81933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
81953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
81963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
81983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
82013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
82023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
82033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
82053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8206bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
82083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
82103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  enter WriteOneJNGImage()");
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
82133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
82143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
82153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
82173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
82183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
82203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
82223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
82233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
82253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
82273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
82283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
82293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
82303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
82333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
82353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
82363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
82393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
82403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
82413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
82423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
82433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
82453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
82463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
82473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
82483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
82493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
82503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
82513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
82523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
82533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
82543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
82553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
82563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
82573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
82583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
82593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
82603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
82613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
82623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
82713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
82733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
82743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
82753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
82763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
82783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
82793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
82803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
82813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
82833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
82843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
82863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
82873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
82883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
82903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
82913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
82933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
82943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
82953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
82963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
82973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
82983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
82993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
83003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
83023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
83033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
83053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
83063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
83073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
83103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
83113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             &image->exception);
83123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
83133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Successfully read jpeg_image into a blob, length=%lu.",
8316bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              (size_t) length);
83173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
83203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
83213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
83223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
83233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
83263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
83273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
83283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JHDR,16L);
83293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+4,image->columns);
83303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGLong(chunk+8,image->rows);
83313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
83323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
83333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
83343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
83353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
83363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
83373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
83383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
83393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
83403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
83413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
83423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG width:%15lu",image->columns);
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG height:%14lu",image->rows);
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
83593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
83613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
83633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-b profiles */
83663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-b",(int) logging);
83673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
83703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
83713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
83733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
83743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
83753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
83763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
83793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8383bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
83843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
83853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
83873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
83883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
8390bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
8392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    LogPNGChunk((int) logging,mng_bKGD,(size_t) (num_bytes-4L));
83933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
83943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
83963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
83993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
84003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
84013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
84023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
84033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
84043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
84053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
84093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
84103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
84113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
84123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
84133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_sRGB,1L);
84143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
84153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (image->rendering_intent-1);
84163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
84173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk[4]=(unsigned char) (PerceptualIntent-1);
84183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
84193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
84203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
84223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
84243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
84263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
84273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
84283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
84293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
84303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_gAMA,4L);
8431bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+4,(size_t) (100000*image->gamma+0.5));
84323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
84333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
84343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
84363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
84373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
84393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
84413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
84423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
84433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
84443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
84453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
84463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_cHRM,32L);
84473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
8448bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+4,(size_t) (100000*primary.x+0.5));
8449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+8,(size_t) (100000*primary.y+0.5));
84503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
8451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+12,(size_t) (100000*primary.x+0.5));
8452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+16,(size_t) (100000*primary.y+0.5));
84533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
8454bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+20,(size_t) (100000*primary.x+0.5));
8455bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+24,(size_t) (100000*primary.y+0.5));
84563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
8457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+28,(size_t) (100000*primary.x+0.5));
8458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+32,(size_t) (100000*primary.y+0.5));
84593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
84603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
84643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
84663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
84673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
84683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
84693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
84703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_pHYs,9L);
84713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
84723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8473bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+4,(size_t)
84743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
8475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          PNGLong(chunk+8,(size_t)
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
84773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
84783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
84803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
84823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8483bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              PNGLong(chunk+4,(size_t)
84843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
8485bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              PNGLong(chunk+8,(size_t)
84863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
84873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
84883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
84903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8491bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              PNGLong(chunk+4,(size_t) (image->x_resolution+0.5));
8492bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              PNGLong(chunk+8,(size_t) (image->y_resolution+0.5));
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
84953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
84983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
85013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
85043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
85053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
85063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
85073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_oFFs,9L);
8508bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
8509bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
85113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
85133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
85153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
85173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
85183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       LogPNGChunk((int) logging,mng_vpAg,9L);
85193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
85203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
85213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
85223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
85243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
85283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
85303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8531bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
85323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
85333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8534bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
85353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
85363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
85383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
85393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Write IDAT chunks from blob, length=%lu.",
8541bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              (size_t) length);
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
85443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
85453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
8546bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
85473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
85483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
85493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
85503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
85513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
85523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
8553bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
8554bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                LogPNGChunk((int) logging,mng_IDAT,(size_t) len);
85553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
85563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
85573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
85583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
85593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
85603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
85613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
85623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Skipping %c%c%c%c chunk, length=%lu.",
85643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *(p),*(p+1),*(p+2),*(p+3),len);
85653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
85663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
85673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
85683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
85703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
85713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
85723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
85733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Write JDAA chunk, length=%lu.",
8575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              (size_t) length);
8576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
85773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
85783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          LogPNGChunk((int) logging,mng_JDAA,length);
85793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
85803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
85813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
85823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
85833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
85843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
85853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
85863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
85893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
85923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
85933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
85943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
85953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
85973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
85993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
86033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
86043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
86063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
86103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Created jpeg_image, %lu x %lu.",jpeg_image->columns,
86153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->rows);
86163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
86183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
86193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
86213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
86223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
86253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
86263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
86283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Successfully read jpeg_image into a blob, length=%lu.",
8630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        (size_t) length);
86313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Write JDAT chunk, length=%lu.",
8634bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        (size_t) length);
86353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
8637bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
86383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_JDAT,length);
86403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
86433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
86453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
86463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
86483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_write_chunk_from_profile(image,"JNG-chunk-e",(int) logging);
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
86533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LogPNGChunk((int) logging,mng_IEND,0);
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
86573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
86583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
86603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
86643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
86703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
86903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
86933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
86953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
86963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
87023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure;
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging;
87063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
87093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteJNGImage()");
87163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
87173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
87183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
87223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
872490823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
87263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
87293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
87353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
87383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
87403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
87413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
87433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
87453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
87503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
87513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
87523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
87533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
87563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
87583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
87593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
87613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
87643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_mng_structure,
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
87663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
87673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
87703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
87713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
87723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
87733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
87743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
87753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    logging,
87763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
87773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize,
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8780bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
87843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
87853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8790bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8797d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
88013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
88053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter WriteMNGImage()");
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
88183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
882090823213d62b0ba18557e61f1e6892c6fffd6cd4cristy  mng_info=(MngInfo *) AcquireAlignedMemory(1,sizeof(MngInfo));
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
88303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
88383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
88413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
88493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=MagickFalse;
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    optimize=(image_info->type == OptimizeType || image_info->type ==
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      UndefinedType);
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
88633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
88673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (optimize)
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: TRUE");
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
88713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Optimize: FALSE");
88733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Image_info depth: %ld",image_info->depth);
88753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
88773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
88793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
88803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Scene: %ld",scene++);
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "      Image depth: %lu",p->depth);
88853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
88863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
88913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
88923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
88943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: %lu",p->colors);
89003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
89013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
89033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Sometimes we get PseudoClass images whose RGB values don't match
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    the colors in the colormap.  This code syncs the RGB values.
89113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
89133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Image
89143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p;
89153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (p->taint && p->storage_class == PseudoClass)
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) SyncImage(p);
89203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->adjoin == MagickFalse)
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_BUILD_PALETTE
89263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (optimize)
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
89293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Sometimes we get DirectClass images that have 256 colors or fewer.
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        This code will convert them to PseudoClass and build a colormap.
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
89363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class != PseudoClass)
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p->colors=GetNumberColors(p,(FILE *) NULL,&p->exception);
89403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p->colors <= 256)
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p->colors=0;
89433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (p->matte != MagickFalse)
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageType(p,PaletteMatteType);
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageType(p,PaletteType);
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
89493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
89523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
89573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
89643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
89733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
89793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
89813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
89823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
89843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
89863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
89873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
89893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
89903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
89913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
89923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
89933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
90033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
90083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
90093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
90113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
90133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
90143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
90163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
90173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
90183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
90193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
90203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
90223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
90233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
90243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
90253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
90263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
90273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
90283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
90293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
90303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
90313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
90323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
90333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
90343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
90363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
90373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
90383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
90403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
90413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
90423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
90433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
90443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
90453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
90483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
90493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
90503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
90603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
90623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
90633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
90663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
90683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
90693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
90713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
90723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
90733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
90753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
90763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
90803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
90813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
90823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
90953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
90963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
90973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
91003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
91033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
91063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
91093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
91113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
91123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
91133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
91143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
91153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 final_delay=10;
91163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 (void) ThrowMagickException(&image->exception,
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
91183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "input has zero delay between all frames; assuming 10 cs",
91193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   "`%s'","");
91203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
91213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
91233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1UL*image->ticks_per_second/final_delay;
91263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
91273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
91343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
91373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
91393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
91403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
91413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
91423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
91443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
91463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
91473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
91513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     LogPNGChunk((int) logging,mng_MHDR,28L);
91523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+4,mng_info->page.width);
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+8,mng_info->page.height);
91543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
91553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
91563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
91633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
91643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
91733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
91833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
91873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
91923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
91933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
91943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
91953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
91993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
9205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
9206bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         LogPNGChunk((int) logging,mng_nEED,(size_t) length);
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
92083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
92143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
92173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_TERM,10L);
92213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
92233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
92243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
92253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
92263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
92273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
92283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
92293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
92303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               "     TERM delay: %lu",
9233bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               (size_t) (mng_info->ticks_per_second*
92343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  final_delay/MagickMax(image->ticks_per_second,1)));
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
92363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9237bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                 "     TERM iterations: %lu",(size_t) PNG_UINT_31_MAX);
92383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
92393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 "     Image iterations: %lu",image->iterations);
92413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
92433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
92443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
92463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
92473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
92483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
92493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
92503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
92533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
92543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
92553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
92563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_sRGB,1L);
92573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
92583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (image->rendering_intent-1);
92593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
92603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) (PerceptualIntent-1);
92613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
92623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
92633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
92643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
92653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
92663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
92673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
92683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
92703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
92713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
92723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
92733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
92743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_gAMA,4L);
9275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+4,(size_t) (100000*image->gamma+0.5));
92763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
92773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
92783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
92793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
92803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
92813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
92823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
92833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
92843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
92863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
92873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
92883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
92893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
92903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_cHRM,32L);
92913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
9292bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+4,(size_t) (100000*primary.x+0.5));
9293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+8,(size_t) (100000*primary.y+0.5));
92943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
9295bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+12,(size_t) (100000*primary.x+0.5));
9296bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+16,(size_t) (100000*primary.y+0.5));
92973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
9298bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+20,(size_t) (100000*primary.x+0.5));
9299bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+24,(size_t) (100000*primary.y+0.5));
93003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
9301bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+28,(size_t) (100000*primary.x+0.5));
9302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+32,(size_t) (100000*primary.y+0.5));
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
93043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
93053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
93063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
93093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
93143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
93153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_pHYs,9L);
93163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
9318bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+4,(size_t)
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
9320bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             PNGLong(chunk+8,(size_t)
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
93223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
93233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
93253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
9328bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                 PNGLong(chunk+4,(size_t)
93293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
9330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                 PNGLong(chunk+8,(size_t)
93313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
93323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
93343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
93353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
9336bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                 PNGLong(chunk+4,(size_t) (image->x_resolution+0.5));
9337bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                 PNGLong(chunk+8,(size_t) (image->y_resolution+0.5));
93383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
93393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
93433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
93453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
93473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
93483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
93503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
93533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
93543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
93553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
93563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_BACK,6L);
93573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
93593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
93603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_bKGD,6L);
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
93763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
93773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
9380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
93873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         LogPNGChunk((int) logging,mng_PLTE,data_length);
9390bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
93983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
94043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
94063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
94073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
94093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
94133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
94283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
94313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
94323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
9433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
94373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                LogPNGChunk((int) logging,mng_PLTE,data_length);
9440bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
94473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
94503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
94603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
94633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
94653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
94703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
94743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             LogPNGChunk((int) logging,mng_DEFI,12L);
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
94803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
94813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
94853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
94893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
94943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
94973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
94983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
95013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,1L);
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
95113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
95123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
95143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
95163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
95173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
95183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
95193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           LogPNGChunk((int) logging,mng_FRAM,10L);
95203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
95213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
95223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
95233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
95253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
95263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
95293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->delay=image->delay;
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
95353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
95373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
95413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
95473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
95483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
95493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
95503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
95523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
95533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
95553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
95573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
95613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
95623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
95643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
95653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
95673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
95693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
95703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
95713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
95723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
95733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
95763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
95783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
95793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
95813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
95823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
95833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
95843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      LogPNGChunk((int) logging,mng_MEND,0L);
95853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
95863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
95873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
95893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
95903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
95913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
95923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
95933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
95943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
95953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
95963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9597d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
95983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
95993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
96003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
96013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
96023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
96033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
96043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
96053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
96063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
96073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
96083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
96093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9610d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
96113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9612