png.c revision 58f77c7678f35e372fd218e4bb0b9cb8937daed7
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%                                                                             %
217e41fe84a841d7b9d7b36b245b65e9dcb3314943cristy%  Copyright 1999-2011 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"
455c7cf4e469a4dad7e277783749155932252c52dfglennrp#include "magick/artifact.h"
465a2ca481ab4ff6751bba842263739966e53441aacristy#include "magick/attribute.h"
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob.h"
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/blob-private.h"
493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/cache.h"
503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color.h"
513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/color-private.h"
524ccd4c0b8623aa47f1c10dd366666799e5957c3ccristy#include "magick/colormap.h"
533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/colorspace.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/constitute.h"
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/enhance.h"
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception.h"
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/exception-private.h"
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/geometry.h"
59f2e1166e90de2dfe2e6a2aed7cd5f73640f34a7acristy#include "magick/histogram.h"
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image.h"
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/image-private.h"
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/layer.h"
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/list.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/log.h"
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/magick.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/memory_.h"
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/module.h"
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor.h"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/monitor-private.h"
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/option.h"
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/quantum-private.h"
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/profile.h"
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "magick/property.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 */
948371ecc013ff231ce380d8717e517312e62e1f01glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
955b927348e949d94f3a64b055eccb03459f115c69glennrp
965b927348e949d94f3a64b055eccb03459f115c69glennrp/* PNG_PTR_NORETURN does not work on some platforms, in libpng-1.5.x */
9775cfe702843fd25dba7cb241c05fa65957c67129cristy#define PNG_PTR_NORETURN
98286a6355c4544b794da2b6df973faad07c69e541glennrp
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (((color).red == (target).red) && \
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).green == (target).green) && \
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ((color).blue == (target).blue))
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
139cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2578182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
266bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
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
39035ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
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
400b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
401b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
402b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
45826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
45926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
46026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
461a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
46226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
46326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
46426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
46526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
46626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
46726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
46826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
46926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
470a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
47126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
47226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
4738d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
4748d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap;
47526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WritePNGImage(const ImageInfo *,Image *);
4840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteMNGImage(const ImageInfo *,Image *);
4870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  WriteJNGImage(const ImageInfo *,Image *);
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4930c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
4940c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
495fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
4960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
4970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
498fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrpLosslessReduceDepthOK(Image *image)
4990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
5009d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
50167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
50267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
50367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
5043faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
5053faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
50667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
50767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
5083faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
5099d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
51005a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
5113faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
5123faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
5133faa9a3fb01696daaf976d595f492cb530bffb21glennrp
51467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
51567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
51667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
51703e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
5180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
5190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        const PixelPacket
5210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
5220c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5230c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
5243faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
5253faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
5263faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
5273faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
5280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
5300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5310c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
5320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5330c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
5340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5353faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
5363faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
5373faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
5383faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
5393faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
5403faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
5413faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
5423faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
5433faa9a3fb01696daaf976d595f492cb530bffb21glennrp
5440c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5453faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
5460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5470c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
5500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
5510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
5530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
5540c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5550c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
5560c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
5570c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5580c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
5590c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
5600c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
5610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5620c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              if (p == (const PixelPacket *) NULL)
5630c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
5640c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
5650c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5660c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
5670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5680c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
5690c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
5703faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
5713faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(GetRedPixelComponent(p)) &&
5723faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(GetGreenPixelComponent(p)) &&
5733faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(GetBluePixelComponent(p)) ?
5743faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
5750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5760c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
5770c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
5780c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5790c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                p++;
5800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
5818640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
5820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
5830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
5840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
5850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
5870c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
5880c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
589fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
5900c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
591a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
592a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
593a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
594fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
595a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
5960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
5970c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
5980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
5990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
6000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
6010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
602e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
603cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
6040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
605e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
606e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
607e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
608e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
6090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
610e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
611e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
6120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
613e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
614e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
6150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
616e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
617e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
6180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
619e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
620e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
621e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
622e610a071534e448c46460a5aa39ede33bf56b329glennrp}
623e610a071534e448c46460a5aa39ede33bf56b329glennrp
624e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
625cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
6260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
627cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
628e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
629e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
630e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
6310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
632e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
633e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
6340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
635e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
636e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
6370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
638e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
639e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
6400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
641e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
642e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
643e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
644e610a071534e448c46460a5aa39ede33bf56b329glennrp}
645e610a071534e448c46460a5aa39ede33bf56b329glennrp
646bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
6580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6610c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
662dbb105fc25903e800273f7e980c0553060858a68glennrp
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
668dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
674dbb105fc25903e800273f7e980c0553060858a68glennrp%   Like IsGrayImage except does not change DirectClass to PseudoClass        %
675dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
676dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
678dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
685dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
686dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
691dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
692dbb105fc25903e800273f7e980c0553060858a68glennrp
693dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
695dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
696dbb105fc25903e800273f7e980c0553060858a68glennrp        if (IsGray(image->colormap+i) == MagickFalse)
697dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
698dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
700bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (const PixelPacket *) NULL)
704dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
705dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
706dbb105fc25903e800273f7e980c0553060858a68glennrp    {
707dbb105fc25903e800273f7e980c0553060858a68glennrp       if (IsGray(p) == MagickFalse)
708dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
709dbb105fc25903e800273f7e980c0553060858a68glennrp       p++;
710dbb105fc25903e800273f7e980c0553060858a68glennrp    }
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
712dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
713dbb105fc25903e800273f7e980c0553060858a68glennrp}
714d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
7840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
7870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
8200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
8230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
832d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
855a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
863a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87603812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
87703812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
881e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
882e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
884d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
890d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the orginal PNG from files that have been converted to Xcode-PNG,
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) FormatMagickString(msg,MaxTextExtent,
1004e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1005e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1033bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
10393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
10490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
10520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
10603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
10613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
10673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
10693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1109bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
11100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1124bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
11350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1136bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
11580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
11630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1178bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
118321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
118521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1187bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
11920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
11960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
12100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
12130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
12160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
12190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1231bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1232bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1233bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1234bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1252bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
12548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
12558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
12560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
12620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12668182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12688182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1271cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
12770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
12810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
12840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1285e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
12868371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
12878371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
12888371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1290faa852bad40107edae19405e76a299057668d795glennrp#else
1291faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1292faa852bad40107edae19405e76a299057668d795glennrp#endif
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1295cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
13020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1306cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
13070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1313cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_voidp Magick_png_malloc(png_structp png_ptr,png_uint_32 size)
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
13210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
13240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1335cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
13363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1348cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_read_raw_profile(Image *image, const ImageInfo *image_info,
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1351bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13670c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
13790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
13830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1384f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
13850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
138697f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
138797f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
138897f90e23c85b9c58387880125c29d8c99126f83aglennrp
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
13910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=AcquireStringInfo(length);
14010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
14130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1414bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
14300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
14390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
14420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
14553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
14563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
14573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1476bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
14780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1479bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
15013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
15043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
15223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1527cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tIME chunk into the date:modify property */
1528cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
1529cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
15344eb3931feb349dd87142c78503b779228f3e1a0fglennrp    intent,
1535cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
15374eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1539faa852bad40107edae19405e76a299057668d795glennrp    pass,
1540faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1541faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1542faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1543faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1544faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
15454eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
15464eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
15474eb3931feb349dd87142c78503b779228f3e1a0fglennrp
15484eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
15494eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1551a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  LongPixelPacket
1552a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    transparent_color;
1553a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
15554383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1558faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
1559faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
1560faa852bad40107edae19405e76a299057668d795glennrp
1561faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
1562faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
1563faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
1564faa852bad40107edae19405e76a299057668d795glennrp
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1575faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
1576faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
1577faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
15784eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_rowbytes,
15794eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
15804eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
1581faa852bad40107edae19405e76a299057668d795glennrp
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
15843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
1586cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
15873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register IndexPacket
15955c6f789db7a30bad01ace12b09ad9cd471339e94cristy    *indexes;
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1597bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
160539992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1608eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
1609eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
1610eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
16153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
1624fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1627cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
16283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
163025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
16343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
163661b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
163761b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
163861b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
163961b4c957269727a0a2526edc2331881da8346100glennrp    {
164061b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
164161b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
164261b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
164361b4c957269727a0a2526edc2331881da8346100glennrp    }
164461b4c957269727a0a2526edc2331881da8346100glennrp#  endif
164561b4c957269727a0a2526edc2331881da8346100glennrp#endif
164661b4c957269727a0a2526edc2331881da8346100glennrp
164761b4c957269727a0a2526edc2331881da8346100glennrp
1648ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1651a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
1652a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
1653a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
1654a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
16550e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
16560e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
16570e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
16580e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
16590e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.opacity=65537;
16600e319739731741c52a6303723e0c8678a0df5579glennrp
1661cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
16624eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
1663cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
1664cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
16653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
16683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
1670cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
1671cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
1674cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
16800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
16843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
16880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1695cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
16960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1697faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
1704cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
17090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
17117b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
17127b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
17137b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
17147b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
17150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1721faa852bad40107edae19405e76a299057668d795glennrp
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
17240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
17363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1757991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
1758991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
1759991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1773991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
1777faa852bad40107edae19405e76a299057668d795glennrp
1778faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
1779faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
1780faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
1781faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
1782faa852bad40107edae19405e76a299057668d795glennrp
1783faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
1784faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
1785faa852bad40107edae19405e76a299057668d795glennrp
1786faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
1787faa852bad40107edae19405e76a299057668d795glennrp
1788faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1790faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
1791faa852bad40107edae19405e76a299057668d795glennrp        {
1792faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
1793faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
1794faa852bad40107edae19405e76a299057668d795glennrp        }
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1796faa852bad40107edae19405e76a299057668d795glennrp
1797faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
1799faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1803e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
1804e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
18050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
1808faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
18090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
1812faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
18130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
1816faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1819faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
1820faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1825e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
1826e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
1827e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1828e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
1829e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
1830e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
1831e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
1832e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
18410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
1860cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1861cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        (mng_info->global_srgb_intent);
18620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
1865cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
1866cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
18670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1870e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1875faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
1876faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
1877faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
18780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1887faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
1888faa852bad40107edae19405e76a299057668d795glennrp    {
1889faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
1890faa852bad40107edae19405e76a299057668d795glennrp        {
1891faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
1892faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
1893faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
1894faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
1895faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
1896faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
1897faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
1898faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
1899faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
1900faa852bad40107edae19405e76a299057668d795glennrp        }
1901faa852bad40107edae19405e76a299057668d795glennrp    }
19020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1903faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
19140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1920e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1922e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
1923cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
1924cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
1925faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
1926faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
1927faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
1928faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
1931faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1933905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
1934905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
19350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1939e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
1940e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
1944faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
1945faa852bad40107edae19405e76a299057668d795glennrp    {
1946faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
1947faa852bad40107edae19405e76a299057668d795glennrp        {
1948faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
1949faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
1950faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
1951faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
1952faa852bad40107edae19405e76a299057668d795glennrp        }
1953faa852bad40107edae19405e76a299057668d795glennrp    }
1954faa852bad40107edae19405e76a299057668d795glennrp
1955faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
19610881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
19620881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
19630881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
19640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
19710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1974e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
1975e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1978823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
1979faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
19880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
1990faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
19960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1997faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
20043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2009bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
20103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2014faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
20163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2023faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2024faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
20250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
20280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
20310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
20340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2046bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2047faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2048faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
20500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2051faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2053bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2054bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2055bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
20620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2063bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      /* Scale background components to 16-bit, then scale
2064bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2065bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
2066bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2067bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2068bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    raw ping_background=(%d,%d,%d).",ping_background->red,
2069bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            ping_background->green,ping_background->blue);
20702cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2071bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
20720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2073bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth == 1)
2074bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
20750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2076bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 2)
2077bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
20780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2079bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 4)
2080bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
20810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2082bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth <= 8)
2083bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
20842cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2085bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2086bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2087bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
20882cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2089bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2090bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
20912cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20922cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
20930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
20942cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
20952cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
20962cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
2097bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
20982cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2099bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2100faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
21010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2102bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2103faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
21040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2105bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2106bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
21070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2108bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.opacity=OpaqueOpacity;
21092cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2110bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2111bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2112bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2113bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2114bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2115bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2117bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2118a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2119faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2122a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
21233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
212735ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
212835ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
212935ef824baa82511126ff0072ae30eee0da9c05a3cristy
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2134f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
21353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2136faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2137faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2138faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2139faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2140faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2141faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
21433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
21443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
21463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2147faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2152a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2153a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2154a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2155a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2156a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2157a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2158a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2159a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2160a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
2161a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.opacity= scale_to_short*ping_trans_color->gray;
216205eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2163faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
21643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
21650f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
21660f111984738842d27d04aed2a3f823d82a943506glennrp              {
21670f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21680f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
21690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21700f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21710f111984738842d27d04aed2a3f823d82a943506glennrp                  "    scaled graylevel is %d.",transparent_color.opacity);
21720f111984738842d27d04aed2a3f823d82a943506glennrp              }
21733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.red=transparent_color.opacity;
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.green=transparent_color.opacity;
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              transparent_color.blue=transparent_color.opacity;
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2182faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2187faa852bad40107edae19405e76a299057668d795glennrp
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2189faa852bad40107edae19405e76a299057668d795glennrp
2190faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2191faa852bad40107edae19405e76a299057668d795glennrp
21923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2196bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2198bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2201faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2202faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
22083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2213faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2214faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2215faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2216faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2218befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2219befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2220befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2222befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2223befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
222667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
222767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
222867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
222967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
22303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2231faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2240bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
22410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
22453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
22523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
22533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
22543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
22550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2256faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
22650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22666af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
22693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22726af6cf1a950b111ad0ac706269a703086693ba71glennrp
227367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
22746af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
22756af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
22766af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
22776af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
22786af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
22793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
22800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2283bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2286faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
22870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
22900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2299147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2300cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2301cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2302147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2303147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2304147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2305147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2306147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2307147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
23087cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp     (void) FormatMagickString(msg,MaxTextExtent,
23097cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
23107cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp     (void) SetImageProperty(image,"PNG:IHDR.width,height    ",msg);
2311147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2312147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
2313147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.bit_depth       ",msg);
2314147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2315147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",(int) ping_color_type);
2316147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.color_type      ",msg);
2317147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2318147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) FormatMagickString(msg,MaxTextExtent,"%d",
2319147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        (int) ping_interlace_method);
2320147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.interlace_method",msg);
2321cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2322147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
23273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
23280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23290ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2330347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2331347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2335e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
23363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
23373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2339cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
23440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
23463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
23510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2353cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2354cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
23550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2357cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2358cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
23590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2360cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
23620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2369faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
23723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
23733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
23743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
23753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2376cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
23773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
23800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2381cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
2382cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
23830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
23870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
23897b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
23907b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
23917b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
23927b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
23930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
23953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2397ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
23980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2399ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2400ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
24010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2402c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2403c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2404c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2405c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2406c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2407c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2408c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
24103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2411c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2412c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2413c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2414c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2415c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
241667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
241767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        int
241867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          depth;
241967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
242067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        depth=(ssize_t) ping_bit_depth;
242167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
2422c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2423c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2424c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2425c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
24260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2427c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2428c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2429c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2430c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
24310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2432c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2433c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
24340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2435cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
2436c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
24373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2438c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (q == (PixelPacket *) NULL)
2439c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
24400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2441c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2443cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayQuantum,ping_pixels+row_offset,exception);
24440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2445c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
24463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2447cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayAlphaQuantum,ping_pixels+row_offset,exception);
24480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2449c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2451cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBAQuantum,ping_pixels+row_offset,exception);
24520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2453c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2454c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2455cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              IndexQuantum,ping_pixels+row_offset,exception);
24560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2457c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2458c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2459cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBQuantum,ping_pixels+row_offset,exception);
24603faa9a3fb01696daaf976d595f492cb530bffb21glennrp
2461c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2462c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2463c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2464a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2465a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2466a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2467a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2468c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2469c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
24705aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
24715aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
24725aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                   (q->opacity != OpaqueOpacity))
2473c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2474a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2475a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2476a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2477a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2478c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2479c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2480c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
24814f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
24824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
2483a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    (ScaleQuantumToShort(q->red) == transparent_color.red &&
2484a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->green) == transparent_color.green &&
2485a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    ScaleQuantumToShort(q->blue) == transparent_color.blue))
24864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2487a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2488a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2489a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
24904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
24914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
24924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2493c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                q++;
2494c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2495c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
24960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2497c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2498c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2499c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2500c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
25010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2502c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2503c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2505c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2506c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2507c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
25080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2509c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
25107a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2511c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
25127a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
25137a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
25147a287bfadeadea12e47c2376ca78a5d101687142cristy          }
25153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
25163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
25170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2519c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
25303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2531faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
25323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
25330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
25353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
25360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
25383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
25390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2540bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
25413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
25423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
2543faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
2544c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
25453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
25463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
2547c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2548cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
25493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
25500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (q == (PixelPacket *) NULL)
25523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
25530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25545c6f789db7a30bad01ace12b09ad9cd471339e94cristy        indexes=GetAuthenticIndexQueue(image);
2555cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
25563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
2557c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2558faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
25593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
25613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2562bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
25633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
25643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2565bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
25663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
25683faa9a3fb01696daaf976d595f492cb530bffb21glennrp                *r++=ScaleCharToQuantum(
25693faa9a3fb01696daaf976d595f492cb530bffb21glennrp                     (unsigned char) ((*p) & (0x01 << bit) ? 0xff : 0x00));
25703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
25713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
25743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2575bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
25763faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  *r++=ScaleCharToQuantum(
25773faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  (unsigned char) ((*p) & (0x01 << bit) ? 0xff : 0x00));
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
25813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
258247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2585bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
25863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
25873faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x55*(*p >> 6) & 0x03));
25883faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x55*(*p >> 4) & 0x03));
25893faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x55*(*p >> 2) & 0x03));
25903faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x55*(*p++) & 0x03));
25913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
25920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
2595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
25963faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  *r++=ScaleCharToQuantum((unsigned char)
25973faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (0x55*((*p >> (i*2)) & 0x03)));
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
25990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
260247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
26043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
26063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26073faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x11*(*p >> 4) & 0x0f));
26083faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x11*(*p++) & 0x0f));
26093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
26123faa9a3fb01696daaf976d595f492cb530bffb21glennrp              *r++=ScaleCharToQuantum((unsigned char) (0x11*(*p >> 4) & 0x0f));
26130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
261647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
26183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2619faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
2620bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
26223faa9a3fb01696daaf976d595f492cb530bffb21glennrp                *r++=ScaleCharToQuantum((unsigned char) *p++);
26233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* In image.h, OpaqueOpacity is 0
26243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * TransparentOpacity is QuantumRange
26253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * In a PNG datastream, Opaque is QuantumRange
26263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 * and Transparent is 0.
26273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q->opacity=ScaleCharToQuantum((unsigned char) (255-(*p++)));
2629c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                if (q->opacity != OpaqueOpacity)
26300b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                q++;
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
26330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
2635bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
26363faa9a3fb01696daaf976d595f492cb530bffb21glennrp                *r++=ScaleCharToQuantum((unsigned char) *p++);
26370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
264047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
26413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
2643bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
264458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp           {
264558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16)
264658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
264758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
264858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
264958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
265058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                *r=((*p++) << 8);
265158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
265258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
265358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                *r=0;
265458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
265558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum=(*r);
265658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
265758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r=(Quantum) quantum;
265858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
265947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2660faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
266258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  quantum=((*p++) << 8);
266358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  quantum|=(*p++);
266458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  q->opacity=(Quantum) (QuantumRange-quantum);
2665c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
26660b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
26673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
266958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else
267058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 32)
267158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
267258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
267358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
267458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
267558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                *r=((*p++) << 8);
267658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
267758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
267858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                *r=0;
26799892945b14ac7dfca49c597dbc66ecec6bd69481glennrp
268058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum=(*r);
268158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
268258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r=quantum;
268358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
26840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2685faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
268758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  q->opacity=(*p << 8) | *(p+1);
268858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  q->opacity*=65537L;
268958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  q->opacity=(Quantum) GetAlphaPixelComponent(q);
269058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  if (q->opacity != OpaqueOpacity)
269158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
269267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                  p+=2;
269358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  q++;
269458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
269558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
269658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
269758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
269858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
269947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
270058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
270158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
270258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  q->opacity=(Quantum) (QuantumRange-(*p++));
2703c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  if (q->opacity != OpaqueOpacity)
27040b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
270558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q++;
27073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
27083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
270958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#endif
271058f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp            }
271147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
271447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27183faa9a3fb01696daaf976d595f492cb530bffb21glennrp
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
27230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2724bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
272580ac8b9110f1adf7202ed1f4f244cbb1a4e1a56fcristy          indexes[x]=(IndexPacket) (*r++);
27260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
27283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
27290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27307a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
27317a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2732cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2733cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
273447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27357a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
27367a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
27377a287bfadeadea12e47c2376ca78a5d101687142cristy          }
27383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
2739c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27407a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
274347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
2747c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2750c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2751c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
2752c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2753c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
2754c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2755c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
2756c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2757c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
2758c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
27595aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
27605aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27615aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
2762a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
27635aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
27645aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
2765c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
2766c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
2767c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2768b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
2769b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
27700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27715c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
27725c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
2773aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
27745c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
27755c6f789db7a30bad01ace12b09ad9cd471339e94cristy
27765c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
27775c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
27785c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
2779aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
27805c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
278147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
27824eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
27833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
2785bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
2788cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
27913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2792cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
279947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2800faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
28033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
28073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
28093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
2810c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28113c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
2812c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
28140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2816c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
28170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
28180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 image->colormap[x].opacity =
28200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                   ScaleCharToQuantum((unsigned char)(255-ping_trans_alpha[x]));
28210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
2822c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
282347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
28240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
28250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
28260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
28270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
28280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
28290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                     transparent_color.opacity)
28300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
28310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    image->colormap[x].opacity = (Quantum) TransparentOpacity;
28320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
28330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
28340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
28360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
283747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2838a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
2839a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
2840a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
28410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
28420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
28430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
28440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
28460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
2847c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (q == (PixelPacket *) NULL)
28490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
2850c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            indexes=GetAuthenticIndexQueue(image);
28520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2853a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
2854a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
2855a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
28560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
28570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
2858a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (ScaleQuantumToShort(q->red) == transparent_color.red &&
2859a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->green) == transparent_color.green &&
2860a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                  ScaleQuantumToShort(q->blue) == transparent_color.blue)
28614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  q->opacity=(Quantum) TransparentOpacity;
28634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
28640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
286567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
28660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
28674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
28684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  q->opacity=(Quantum) OpaqueOpacity;
28694f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
2870a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
28710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              q++;
28730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
28740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
28760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
2877c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
28780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
2879a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
2880c11cf6a442f3046940608a5743a68cc891deb13eglennrp
28813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
28823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
2884b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
2885b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
2886b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
288747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
2888eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
28894eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
28904eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
2891a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
2892a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
28934eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
2894a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
2895a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
28963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
28974eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
28984eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
28994eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
29004eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
29010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29024eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
29034eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29044eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
29050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29064eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
29074eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
29084eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) Magick_png_read_raw_profile(image,image_info,text,(int) i);
29094eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
29104eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
29114eb3931feb349dd87142c78503b779228f3e1a0fglennrp
29124eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
29134eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
29144eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
29154eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
29164eb3931feb349dd87142c78503b779228f3e1a0fglennrp
29174eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
29184eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
29194eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
29204eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
29214eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
29224eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (void) ThrowMagickException(&image->exception,GetMagickModule(),
29234eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  ResourceLimitError,"MemoryAllocationFailed","`%s'",
29244eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  image->filename);
29254eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
29264eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
29274eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
29284eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
29294eb3931feb349dd87142c78503b779228f3e1a0fglennrp
29304eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
29314eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
29324eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
29334eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
29344eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
29354eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
29364eb3931feb349dd87142c78503b779228f3e1a0fglennrp               (void) SetImageProperty(image,text[i].key,value);
29373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29384eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
29393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29404eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29414eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
29424eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
29434eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
29443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29464eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
294797f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
29484eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
29494eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
29503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29513c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
29523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
29533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
29543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
29553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
29563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
29573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
29613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
29623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
29633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
296473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
29650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
29673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
29683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
29693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
297247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
29743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
29800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
29860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
29883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
29893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
29923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
29930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
29953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
29960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
29983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
29990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
30023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
30033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
30040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3005faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
30063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
30070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3008faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3009faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3010faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3011faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3012faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3013faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3014faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3015faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
30160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3017faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
30203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
30233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
30263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
30293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
30303c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
30323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
30333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
303647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
30383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
30413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
30420a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
30430a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp   /* Set image->matte to MagickTrue if the input colortype supports
30440a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
30450a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
30460a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
30470a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
30480a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
30490a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
30500a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        MagickTrue : MagickFalse;
30510a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3052cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3053cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3054cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3055cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3056cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
30574eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3058cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3059cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
3060cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) FormatMagickString(msg,MaxTextExtent,
3061613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
3062cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text                 ",msg);
3063cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3064cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3065cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3066cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3067cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) FormatMagickString(msg,MaxTextExtent,
3068cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
3069cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text-encoded profiles",msg);
3070cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3071cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3072cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
30735961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
30745961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) FormatMagickString(msg,MaxTextExtent,"%s",
30755961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
30765961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) SetImageProperty(image,"PNG:cHRM                 ",msg);
30775961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3078cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3079cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
30805961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
30815961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) FormatMagickString(msg,MaxTextExtent,"%s",
30825961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
30835961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) SetImageProperty(image,"PNG:bKGD                 ",msg);
30845961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
30855961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
30865961225e531a5f26ae179c1d919582d5cdaa44bbglennrp     (void) FormatMagickString(msg,MaxTextExtent,"%s",
30875961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3088cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3089cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
3090cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:iCCP                 ",msg);
3091cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
30924eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
30934eb3931feb349dd87142c78503b779228f3e1a0fglennrp        (void) SetImageProperty(image,"PNG:tRNS                 ",msg);
30944eb3931feb349dd87142c78503b779228f3e1a0fglennrp
30954eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
3096cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
30974eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
309807523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
309907523c7d2e40370804c2036295571e4b6426f94dglennrp            "intent=%d (See Rendering intent)",
31004eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (int) intent);
31014eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:sRGB                 ",msg);
31024eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31034eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
31044eb3931feb349dd87142c78503b779228f3e1a0fglennrp
31054eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
31064eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
310707523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
310807523c7d2e40370804c2036295571e4b6426f94dglennrp            "gamma=%.8g (See Gamma, above)",
31094eb3931feb349dd87142c78503b779228f3e1a0fglennrp            file_gamma);
31104eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:gAMA                 ",msg);
31114eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3112cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31134eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3114cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
31154eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
311607523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
311707523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
31184eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
31194eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:pHYs                 ",msg);
31204eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31214eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3122cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31234eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
31244eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
31254eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
31264eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) FormatMagickString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
31274eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
31284eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:oFFs                 ",msg);
31294eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
31304eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
31314eb3931feb349dd87142c78503b779228f3e1a0fglennrp
313207523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
313307523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
313407523c7d2e40370804c2036295571e4b6426f94dglennrp       {
313507523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) FormatMagickString(msg,MaxTextExtent,
313607523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
313707523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
313807523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) SetImageProperty(image,"PNG:vpAg                 ",msg);
313907523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3140cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3141cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
31443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3147cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3149cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
31503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
31513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
31533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
31550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
31573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
31593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
31623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
31633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
31643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
31653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
31663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
316821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
316921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
31703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
31733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
31763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
31803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
31833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
31843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
31853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
318647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
31883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
31893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
319047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
31923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3193fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
31943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
31953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
31963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
319747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
31993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
320047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
32033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
320547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3206dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
32073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
320847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
32113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
321373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
321447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
321747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
32213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
322847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
32323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
32350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
32430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
32453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
324647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
324847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
32503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
32540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
32563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
325747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32583faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if 0 /* This is probably redundant now */
32593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG8") == 0)
32603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,PaletteType);
32620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->matte != MagickFalse)
32643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
32653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* To do: Reduce to binary transparency */
32663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
32673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32683faa9a3fb01696daaf976d595f492cb530bffb21glennrp#endif
326947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
32713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
32733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
32743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
32750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
32773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
32780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
328097f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
328197f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
328297f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
328397f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
328497f90e23c85b9c58387880125c29d8c99126f83aglennrp
328597f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
32863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
32870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
32893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
32903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
32943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
32953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
32993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
33003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
33013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
33023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
33033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
33063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
33073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
33083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
33093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
33113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
33133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
33153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
33183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
33203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
33223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
33243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
33253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
33263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
33273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
33283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
33293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
33303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
33323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
33333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
33343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
33363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
33373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
33383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33394383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
33404383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
33414383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3342bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
33433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
33443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
33463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
33473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
33493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
33503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
33513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
33533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
33543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
33553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
33563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
33573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
33583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
33593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
33603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
33613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const PixelPacket
33633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
33643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3365bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
33663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
33673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
33683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register PixelPacket
33703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
33713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
33733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
33763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
33773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
33783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3380bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
33813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
33823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
33843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
33863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3394fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
33970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
33993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
34003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
34060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
34080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
34110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
34153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
34213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
34390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
34420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
34443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
34453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
34463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
34473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
34493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3450e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3451e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
34523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
34550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
345847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
34620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
34650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3466bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
34680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
347147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
34773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
347847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
34803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
34813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
34833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
34843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
34853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3486bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
34873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3488bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
34893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
34903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
34913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
34923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
34933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
349447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
34963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
349747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
34993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
35003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
35013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
350247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
35043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3506f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
350747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3509f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
351047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
351347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
35163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
351747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
35203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
352147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
35243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
352547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
35283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
352947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
35323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
353347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
35363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
353747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
35403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
35413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
35423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
354347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
35453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
354647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
35483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
35493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
35523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
35533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
35543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
35553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
35563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
35573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
35583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
35593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
35603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
35613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
356273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
356347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
35653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
356647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
35673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
35683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
35690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
35713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
35743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
35760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
35800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
35823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
358773bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
35880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
35903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
35910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
35940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
36050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
36090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
36120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
36210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
36240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
362703812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
36283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
36323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
36353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
36403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
36433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
364447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
36493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
365147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
365447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
366347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
36703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3671bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
367303812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
36743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
36783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
36813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
36820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
368847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
36893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
36923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
36980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
37063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
37080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
37300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
37388182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
37390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37488182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
37498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
37508182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
37518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
37528182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
37538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
37548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
37558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
375747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
37633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
37653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3766e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
3767cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
377847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
37853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
37875eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
37885eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
37890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
37923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
379647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
37990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
38078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
38088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
38160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3824fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
38293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
38313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
38343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
38370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         opacity samples of main image.
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
386647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
38700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(color_image_info->filename,MaxTextExtent,"%s",
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
38730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
38760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
38813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
38853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
38883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
38900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  length=image->columns*sizeof(PixelPacket);
38940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CopyMagickMemory(q,s,length);
390047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
39040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
39060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
39113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
391703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
39203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
39210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
39230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
39253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading opacity from alpha_blob.");
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) FormatMagickString(alpha_image_info->filename,MaxTextExtent,
39293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
39303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
39320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
3934bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
39363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &image->exception);
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
393947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
3941bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
39430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
3945bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy               for (x=(ssize_t) image->columns; x != 0; x--,q++,s++)
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q->opacity=(Quantum) QuantumRange-s->red;
39483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (q->opacity != OpaqueOpacity)
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
39510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
39563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
39603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
396347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
396447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
39663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
39693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
39700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
39720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
39740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
39750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
39780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
39800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
39840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
39850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
39860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
39870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
39893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
39910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
39950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
40113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
40143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
40283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
40323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
40353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
403721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
403821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4058fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
40620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
40650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
40673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
406947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
407047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
407247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40733b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
40743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
40750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
407647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
407747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
407973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
40800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
408447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
408547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
40930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
40963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
41010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
41050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
410947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
41113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
41150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
41210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
41243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
41343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41354383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
413621f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
413721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
41384383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4145bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
41463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
41533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
41613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4170bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
41713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
41723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
41743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
41753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4176bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
41773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
41783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
41803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
41893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
41903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4193bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
42013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
420238ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
420338ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
420438ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4205bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
42103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
42123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
42193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
42223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
422747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
422847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
42303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
42313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4234fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
42380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
42410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
424547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
424647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
424747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
424873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
42490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
425347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
425447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
42603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
426447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
426847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
426947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4272bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4273bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
427747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
42893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
42943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
42963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
42993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
43133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
43163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
43173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4320e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4321e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
43223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
43243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
43250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
43273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
43280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
43310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
43333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
433547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
433847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4339bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
434147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
43463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
43550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
43573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
43620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
43660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
43683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
43703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
437147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
43733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
43743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
43753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
43760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
43783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
43790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
43830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
43860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
43910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4392bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
43940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4398e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
43993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4400e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
44048182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
44050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
44073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
44080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
44103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
44113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
44120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
44143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
44150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
44173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
44198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
44203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
44230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
44260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
44290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
443647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
44380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
44410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
44490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4450e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (void) FormatMagickString(page_geometry,MaxTextExtent,
4451e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4452f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
44530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4455bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
44590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
44620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
44750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44788182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
44798182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
44800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
44830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
44920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4494e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
44950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4497e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
44990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
45043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
45073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
45083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
45110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
45143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
45153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
45160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
45183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
45203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
45363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
45380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
45400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
45430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
45500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
45510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
45530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
45540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
45563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4558e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4559f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
45600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4562e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4563f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
45703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
45713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
45723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
45730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
45800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
45850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
45880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
45910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
45940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
46030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
46060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
46110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
46140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
46170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.opacity=OpaqueOpacity;
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
462947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
463247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
463347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
46373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
46383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
46390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
46460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
464735ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
46560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
46620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
466647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
4672bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
46733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
46763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
467912560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
46803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
46823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
46833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
46843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4687bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
46883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
46893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46908182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
46940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
46970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
46993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
47033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
470447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
470547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
47073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
47088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
47098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
47108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
47128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
47148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
47168182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
47188182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
47208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
472547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
472947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4737e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
4738cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
474347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
474747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4750fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
47553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
475747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
476047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
47663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
47670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
47700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
47733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
477447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
47763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
47780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
47820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
478547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
478647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
478847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4789bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
47903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
479147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
479347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4794bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
47973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
480547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
48098182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
48100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48118182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
48128182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
48130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4814bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4815bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
48160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
48183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
48190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
48210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4824e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
482647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
4829bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
4830bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
48310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4832bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
4833bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
48340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4835bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
4836bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
48370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
48393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
48400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
48420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4845e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
484747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
48530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
4857e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
4858e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
485947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
48613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
48670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
48693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
48700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4871bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
48733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
48763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4879e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
4880e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
48810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
48843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
488547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
48863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
48873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
48883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
488947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
48923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
48943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
489647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
48990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
49010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
49080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
49103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
49110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
49133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
49143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
49153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
49183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
49220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
4926e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
4927e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
49343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
494447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
49463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
49513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
495647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
498047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
498147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
49853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
49893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4990bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4993bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
49943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
49973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
500547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5008bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
501247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
501347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
50153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5016bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
50293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
503347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
50383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
50413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
504347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
504447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
50458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
50460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5049e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5050e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
50510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
50533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
50540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
506547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
50673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
506947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
50753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
508147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
50880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
50910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5092e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5093f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
509447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
50973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
50990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
51013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
510447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
51073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
51143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
512247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
512647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
51323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
513347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
513647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
51403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
51433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
51443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
51453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
51473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
51493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
51530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
51560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
51590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
51643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
517047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
51723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
51733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
517647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
518247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
518547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
519147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
519447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
520047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
520347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
52053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
520947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
521247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
52173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
521847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
522147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
52233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
52243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
52263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
522747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
523047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
523647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
524047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
52433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
52443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
52453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
52463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
52473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
524847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
52503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
52513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
52543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
52593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
52613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
52643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
52653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
52663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
526747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
52693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
52713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
527447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
527747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
528447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
528747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
52913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
529247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
52943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
53023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
53063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
53088182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
53108182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
531447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
53213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
532347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
532947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
53313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
533447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
53363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5337bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5339bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
53433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
53463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
534747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
535047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
535347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
535647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
535947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
536247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
536547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
537347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
537647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
537947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
538447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
539447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
540147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
540447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
54063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
54093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
541047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
541847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54198182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
54208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5433bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
54343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5435bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
54403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
544347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
54473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
54483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
545047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
545447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
546147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
546447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
546547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
546647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
54683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
54753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5478e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5479e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
54803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
54843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
54853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
54863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
54893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
54953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
549647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
55003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
550347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
55060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
55080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
55150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
551847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
55233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
55263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
55273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
55283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
55290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5533e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5534e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
553847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
554547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
55573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
55580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
55610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
55700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
55760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
55790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
558547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
55883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
558947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
55913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
559447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5595bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
559647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
56053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
560847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
56113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
56173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
56203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
562147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
56293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
56330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
56353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
56383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
56443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
565447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
565747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
565947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
566047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
566247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56654e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
566647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
566947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
56713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
567247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
567447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
567547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
567747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
568147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
568447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
568647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
568747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
568947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56924e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
569347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
569647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
569947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
570147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
570247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
570447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
57093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
57123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
57193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  x;
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                register PixelPacket
57223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PixelPacket
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *next,
57273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *prev;
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                png_uint_16
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methx,
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  magn_methy;
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
573347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
573447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
573847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
574047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
57453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
57493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57563faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
57583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
5764bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
576847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5769bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->red=ScaleQuantumToShort(q->red);
57723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->green=ScaleQuantumToShort(q->green);
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->blue=ScaleQuantumToShort(q->blue);
57743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q->opacity=ScaleQuantumToShort(q->opacity);
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          q++;
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
577747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
57823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
57853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
578847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
57913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    large_image->background_color.opacity=OpaqueOpacity;
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
579347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
579647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
579947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
580247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
58083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5811e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
5812bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
58143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*next));
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) AcquireQuantumMemory(length,sizeof(*prev));
581747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if ((prev == (PixelPacket *) NULL) ||
58193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (next == (PixelPacket *) NULL))
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
582647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
582947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5830bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
5833bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
583447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5835bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
5836bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
583747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5838bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
5839bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
584047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5841bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
584347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
5845bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
584647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
585047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5851bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
58533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
58543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
58553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
585747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    register PixelPacket
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5863bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          1,exception);
58683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
586947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5872fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
58783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels); /* replicate previous */
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
588347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
58853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
588847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
5892bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).red=(QM) (((ssize_t) (2*i*((*n).red
5893bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).red)+m))/((ssize_t) (m*2))
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).red);
5895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).green=(QM) (((ssize_t) (2*i*((*n).green
5896bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).green)+m))/((ssize_t) (m*2))
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).green);
5898bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).blue=(QM) (((ssize_t) (2*i*((*n).blue
5899bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).blue)+m))/((ssize_t) (m*2))
59003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).blue);
590147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
5903bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 (*q).opacity=(QM) (((ssize_t)
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (2*i*((*n).opacity
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).opacity)+m))
5906bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).opacity);
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
590847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
59133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
59143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
591847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
592447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
592747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
5930bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                              (*q).opacity=(QM) (((ssize_t) (2*i*((*n).opacity
5931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m))/((ssize_t) (m*2))
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n++;
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pixels++;
59383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
593947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
59413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
594247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
594547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                prev=(PixelPacket *) RelinquishMagickMemory(prev);
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next=(PixelPacket *) RelinquishMagickMemory(next);
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
59503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5964e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5966bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
59673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  register PixelPacket
59693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pixels=q+(image->columns-length);
59733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=pixels+1;
597447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5975bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
5976bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
5978bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
5979bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5981bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
5982bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
598347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5984bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
5985bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
598647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5987bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
598947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
5991bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
599247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
59963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          *q=(*pixels);
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
600047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
60023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            *q=(*pixels);
600547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).red=(QM) ((2*i*((*n).red
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).red)+m)
6011bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).red);
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).green=(QM) ((2*i*((*n).green
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).green)
6014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 +m)/((ssize_t) (m*2))+(*pixels).green);
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).blue=(QM) ((2*i*((*n).blue
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 -(*pixels).blue)+m)
6017bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 /((ssize_t) (m*2))+(*pixels).blue);
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(QM) ((2*i*((*n).opacity
6020bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                   -(*pixels).opacity)+m)/((ssize_t) (m*2))
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   +(*pixels).opacity);
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
602347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*pixels).opacity+0;
60293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
60303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 (*q).opacity=(*n).opacity+0;
60313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
603347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*pixels);
603947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                             *q=(*n);
604247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              (*q).opacity=(QM) ((2*i*((*n).opacity
6047bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                                 -(*pixels).opacity)+m) /((ssize_t) (m*2))
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 +(*pixels).opacity);
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      q++;
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n++;
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++;
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
605647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60603faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6066bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
60683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
606947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6070bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->red=ScaleShortToQuantum(q->red);
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->green=ScaleShortToQuantum(q->green);
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->blue=ScaleShortToQuantum(q->blue);
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q->opacity=ScaleShortToQuantum(q->opacity);
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        q++;
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
607847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
60923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
60943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
60953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
60973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
61003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
61013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
61043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
61073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
61093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
61103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
611247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
61213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
61243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
61273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6128bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6129bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
61313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
613547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
61373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
61393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
614747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
61513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
61523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
61533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
61543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
61553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
61563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
61573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
61613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
61653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
61663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
61683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
61693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61702b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
61712b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
61722b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
61732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
61742b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
61752b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
61762b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
61772b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
61783faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
61798640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
61808640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6182d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
618447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6188bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6191d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6195d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
619747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
619947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
620347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
62063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
62073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
62093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
62103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
62113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
62140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetAuthenticPixelQueue(image) != (PixelPacket *) NULL)
62163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
622547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
62273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
622947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
62323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
62353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
62383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
62413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
62420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
62450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
62500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
62530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
62553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
62563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
62573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
62583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
626147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
626547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
62700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
62723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
62733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
62743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
627547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
62773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
62783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
62793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
62803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
628147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
62843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
62853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
628947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
629447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
62963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
62993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
630047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
63023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
630347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
630647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
63083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
63093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
63140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
63170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
63200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
63223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
63243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
632547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
63273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
63310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
63330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6336e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6337e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
63380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
63393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
63403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
63423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
634647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
63483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
634947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6351e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
635247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
63543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
63563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6357e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
63583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
63593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
63603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
63623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
63643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
63653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
63663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
63673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
63683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
63703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
637447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
63763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
637747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
63793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
638047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
63823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
638347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
63873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
63883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
63893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
63903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
63913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
639247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
63943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
639547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
63973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
63993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
64003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
64013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
64023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
64033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
64043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
64053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
64063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
64073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
64083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
64113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
641247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
64143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
64183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
64193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
642247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
642547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6427e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6428e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
642947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6431f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6432f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
643347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6434f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6435e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6436e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6437f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6438f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
643947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
644347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
644647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
644925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
645447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
64563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
645747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
64593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
646047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
64623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
64643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
646525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
64663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
64673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
64693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
64743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
64773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
64833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
64843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
64853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6488bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6491bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
64923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
64933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
64943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
64953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
64973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
64983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
65033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
650447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
65063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
65083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
65093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
651047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
65123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
65143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
65153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
65163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
651847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
65213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
652247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
65243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
65273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
653047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
65323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
653347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
65373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
653847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
65403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
654147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
654447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
655047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
655547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
65593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
656047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
656347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
656847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
657347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
65753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
65763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
65783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
65823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
658347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
658747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
65913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
65923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
659447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
65963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
659747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
65993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
66003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
66013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
660247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
66043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
661047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
661547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
662347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
663047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
663747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
663818b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6639cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
664018b17443128598500357da7bff2f01683cf32890cristy#endif
664147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
667247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
6674cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
6675cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
668025c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
66963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
66983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
66993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
67003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
67023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
67043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
67063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
67103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
67143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
67213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
67233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
67403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
67513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
6756cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6763bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
67683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
67713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
67840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
67850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
67870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
67913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
67943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
67963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
68013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) FormatMagickString(dp,allocated_length-
6806f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
68073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
680847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6809bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
68153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
681647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
68203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
682347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
682647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
68293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6832cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
68334383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
68403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
68433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
684747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
684847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
684947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
685147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
6855cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
685747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
685847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
685947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
686047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
686147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
686247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6863cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
6864cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
6865cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
686647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
686747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
686847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
686947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
687047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
687147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
687247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
6873cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
687447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
68753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
687647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
68783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
687947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6883b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6884b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
6886b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6888b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
6889b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
6890b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
6891b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
6892b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
6893b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
68953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
69003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
69033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
69063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
6907cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
6908cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
6909e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
6910e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
69115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
691239992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
691339992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
69165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
69175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
69185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
69213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
69265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
69275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
69285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6929bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
693358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
693421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
693558e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
693658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
6937da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
6938fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
6939d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
69408d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
694139992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
6942991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
6943991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
6944991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
694526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
694626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
694726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
6948a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
6949e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
695026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
695126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
695226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
695326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
695426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
695526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
695626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
6957e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
695826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
695926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
696026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
696126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
69628d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
69630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
69640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
696582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
6966d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
6967d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6972bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
69753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
6977cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
6980f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
69810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
69825af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
69835af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
69845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
69855af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
69865af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
69875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
6988bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
69895af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
69905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
69913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6992bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6997dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
6998fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
6999f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
70008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
70018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
70028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7003dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7004dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7005dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7006dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7007dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7008dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7010fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7012b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
7013b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
70148d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (image_info == (ImageInfo *) NULL)
70157b2cc79f1f54b48a9c3fe4eb3afbc2ebd6f6ec08glennrp     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7016b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
70173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7018cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
70220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
70235af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
70245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
70255af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
70265af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
70275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
70285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
70295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
70305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
70315af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
70325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
70335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
70345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
70355af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
70365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
70375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
70385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
70395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7040dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7041dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7042dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7043dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7044da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7045d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
70468d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
704739992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7048991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7049991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7050991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7051991d11dd9c33e65872778b81aff1347cd2878154glennrp
70520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
70530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7054a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
7055dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
70560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
70570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
70580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
70590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
70600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
70610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
70620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7063dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
70640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
70650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
70660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
70670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70688d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
70690e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
70700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
70718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
70728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
70738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
70748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7075fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7076fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7077fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7078fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7079fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7080fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7081fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7082fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7083fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7084fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7085fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7086fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
708728af3713c9111a471cc868c787760de89236fa3cglennrp
708828af3713c9111a471cc868c787760de89236fa3cglennrp  if (image->storage_class != PseudoClass && image->colormap != NULL)
708928af3713c9111a471cc868c787760de89236fa3cglennrp    {
709028af3713c9111a471cc868c787760de89236fa3cglennrp      /* Free the bogus colormap; it can cause trouble later */
709128af3713c9111a471cc868c787760de89236fa3cglennrp       if (logging != MagickFalse)
709228af3713c9111a471cc868c787760de89236fa3cglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
709328af3713c9111a471cc868c787760de89236fa3cglennrp          "    Freeing bogus colormap");
709428af3713c9111a471cc868c787760de89236fa3cglennrp       (void *) RelinquishMagickMemory(image->colormap);
709528af3713c9111a471cc868c787760de89236fa3cglennrp       image->colormap=NULL;
709628af3713c9111a471cc868c787760de89236fa3cglennrp    }
7097fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->colorspace != RGBColorspace)
70993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
71000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
71013241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
71023241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
71033241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
71043241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
71053241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
71063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
71073241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7108a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7109a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7110a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7111a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7112a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7113a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7114a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7115a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7116a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7117a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7118a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
711967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* To do: Option to use the original colormap */
712067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (ping_preserve_colormap != MagickFalse)
7121cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    {
712267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    }
712367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
71249d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp
71253faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if 0 /* To do: respect the -depth option */
712667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
712767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
7128cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
712967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
7130cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
713167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
713267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
713370e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
7134a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
71352b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
71362b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
71372b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
71382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
71392b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  if (image->depth > 16)
71402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
71412b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
71422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
71433faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7144c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
71458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
71468640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
71478640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
71488640fb5e9b1094f35f8beab436f81661b8a99448glennrp
7149c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
7150e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
7151e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
7152e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * RGBA palette and run again, and finally to a simple 3-3-2-1 RGBA
7153e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * palette.  The final reduction can only fail if there are still 256
7154e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * colors present and one of them has both transparent and opaque instances.
7155c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
715682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
715782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
7158d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
715982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
7160d337164012450d70d62e71cf4a308a29004f7d57glennrp  for (j=0; j<5; j++)
7161d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
7162d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
7163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
7165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
7166d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
7168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
7169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
7170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
7171d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
7172d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7173d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * If image->matte is MagickFalse, we ignore the opacity channel
7174d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
7175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7176d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
7177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
7178d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
7179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7180d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
7181d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
7182d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
71833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7184d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   ExceptionInfo
7185d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *exception;
71868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
7188d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
71898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7190d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   PixelPacket
7191d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
7192d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
7193d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
71948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register IndexPacket
7196d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *indexes;
71978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7198d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   register const PixelPacket
7199d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *s,
7200d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *q;
7201d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7202fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   register PixelPacket
7203fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
7204fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7205d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7207d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
7208d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7211d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7212d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
7213d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
7215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
721703812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7218d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
72193c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7220fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
72217ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
72227ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
72248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7225d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "        i    (red,green,blue,opacity)");
72262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7227d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
72287ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
7229d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7230d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7231d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7232d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7235d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
72367ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
72372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
7239d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7240d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
7241d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7242d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7243d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7244d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7245d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
7248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].opacity);
7249d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
7251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
72522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7254d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
725583c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
7257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "        (zero means unknown)");
72597ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
72608d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
72618d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
72628d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
7263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
72647ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7265d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     exception=(&image->exception);
7266d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7267d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
7268fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
7269fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
7270fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
72712cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
7273d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7274d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
72757ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7276d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (q == (PixelPacket *) NULL)
7277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
727897fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
7279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
7280d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7281d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (image->matte == MagickFalse || q->opacity == OpaqueOpacity)
72828d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7283d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
72848d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
7286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0]=*q;
7288d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[0].opacity=OpaqueOpacity;
7289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
7290d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7291d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7292d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
7293d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7294d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(opaque+i, (PixelPacket *) q))
7295d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7297d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7298d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_opaque &&
7299d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque < 259)
7300d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
7302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i] = *q;
7303d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       opaque[i].opacity = OpaqueOpacity;
7304d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
73058d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
73068d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (q->opacity == TransparentOpacity)
73088d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
73108d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
7312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7313d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[0]=*q;
7314d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.red=(unsigned short)(q->red);
7315d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.green=(unsigned short) (q->green);
7316d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.blue=(unsigned short) (q->blue);
7317d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       ping_trans_color.gray=(unsigned short) (q->blue);
7318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
7319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7320d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7321d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
7322d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(transparent+i, (PixelPacket *) q))
7324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
7328d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
7329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7330d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
7331d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       transparent[i] = *q;
7332d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
73338d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
73348d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
7335d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7336d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
7338d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
7340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7341d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[0]=*q;
7342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
7343d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
73448d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7345d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
7346d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       if (IsColorEqual(semitransparent+i,
7348d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          (PixelPacket *) q) &&
7349d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          q->opacity == semitransparent[i].opacity)
7350d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
7351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7352d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7353d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
7354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
7355d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
7356d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
7357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       semitransparent[i] = *q;
7358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7359d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
73608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
7361d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           q++;
7362d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
7363d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
73643c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7365d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (ping_exclude_bKGD == MagickFalse)
7366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
7368d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
7369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
7371d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7372a080bc32a4a8b2ffec83fd836a28753959175363glennrp             if (IsColorEqual(opaque+i, &image->background_color))
7373d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             break;
7374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7375a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7376d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
737703812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
7378d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i]=image->background_color;
7379d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               opaque[i].opacity = OpaqueOpacity;
7380d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               number_opaque++;
738103812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
7382a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
7383a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7384a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
7385d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
73862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7387d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
73883241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7389a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
7390a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
7391a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
7392a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
7393a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
7394a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
7395a080bc32a4a8b2ffec83fd836a28753959175363glennrp
7396d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7397d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7398d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
7399d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7400d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
74013241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7402d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
7403d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7404d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
7405d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
74063241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
74078d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
74088d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
74098d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
7410fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
7411d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7412d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
7413d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
74143241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7415d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
7416d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7417d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
7418d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7419d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
74206185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7421d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (q == (PixelPacket *) NULL)
7422d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
74236185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7424d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
7425d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
7426d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
74276185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7428d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_color == MagickFalse)
7429d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7430d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7431d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
7432d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   {
7433d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != s->green || s->red != s->blue)
7434d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7435d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_color=MagickTrue;
7436d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          ping_have_non_bw=MagickTrue;
7437d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                          break;
7438d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7439d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7440d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7441d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
74423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7443d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
7444d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7445d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
7446d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
74476185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
7448d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     if (s->red != 0 && s->red != QuantumRange)
7449d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
7450d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
7451d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
7452d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     s++;
7453d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
7454d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
7455d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7456d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           }
7457d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
74584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
7459d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
7460d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7461d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         PixelPacket
7462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
7463d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7464d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
7465d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
7466d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7467d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7468d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
7469d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7470d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
7471d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7472d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
7473d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7474d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
74753241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7476d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
7477d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
74783241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7479d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
7480d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
7481d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7482d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
7483d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
7484d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7485d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7486d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
7487d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
7488d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
7489d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
7490d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7491d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
7492d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7493d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
7494d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
7495d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
7496d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
7497d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
7498d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
7499d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
7500d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7501d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7502d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7503d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7504d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
7505d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
7506d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7507d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
75083241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7509d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
7510d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
7511d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
7512d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
7513d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
7514d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
7515d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
75166185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
7517d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
7518d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7519d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
7520d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
75212cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7522d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7523d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
7524d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7525d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7526d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
7527d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7528d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (AcquireImageColormap(image,image_colors) ==
7529d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
75303faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
75313faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
7532d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7533d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
7534d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
7535d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7536d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
7537d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7538d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7539d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
7540d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
7541d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7542d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7543d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
7544d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7545d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7546fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
7547fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7548d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
7549d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
7550d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              q=GetAuthenticPixels(image,0,y,image->columns,1,
7551d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  exception);
75523c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7553d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (q == (PixelPacket *) NULL)
7554d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
75553c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7556d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              indexes=GetAuthenticIndexQueue(image);
7557d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7558d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
7559d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
7560d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
756103812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
7562d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
7563d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      image->colormap[i].opacity == q->opacity) &&
7564d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (IsColorEqual(&image->colormap[i],
7565d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         (PixelPacket *) q)))
75666185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
7567d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    indexes[x]=(IndexPacket) i;
7568d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
75696185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
757003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
7571d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                q++;
7572d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
7573d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7574d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
7575d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
7576d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
7577d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
7578d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
7579d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7580d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
7581d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
7582d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7583d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
7584d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7585d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
7586d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
7587d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7588d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 "       i     (red,green,blue,opacity)");
758983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7590d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
7591d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
759272988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
7593d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
7594d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7595d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
7596d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
7597d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
7598d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
7599d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
7600d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].opacity);
7601d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
76026185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
76036185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
76043c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7605d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
7606d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7607d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
7608d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
7609d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
76103c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7611d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7612d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
76133c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7614d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
7615d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7616d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
7617d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
761803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
7619d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7620d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7621d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
76226185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7623d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
7624d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7625d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
7626d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
76276185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
7628d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7629d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7630d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
7631a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7632d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
7633d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7634d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
7635a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7636d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
7637d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7638d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
7639d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7640d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
7641d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7642d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
76436185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
764403812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
764503812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
7646d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
76473c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7648c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
7649c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7650fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7651c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
7652c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
7653c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
7654c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
7655c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
7656c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
7657fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7658c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
7659c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     * opacity to 0 or OpaqueOpacity
7660c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7661c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (number_semitransparent != 0)
7662c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7663c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7664c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
7665fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7666c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
7667c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7668c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          r=GetAuthenticPixels(image,0,y,image->columns,1,
7669c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              exception);
7670fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7671c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (r == (PixelPacket *) NULL)
7672c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
7673fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7674c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
7675c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
767682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r->opacity = r->opacity > TransparentOpacity/2 ?
767782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                   TransparentOpacity : OpaqueOpacity;
7678c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              r++;
7679c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7680c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7681c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
7682c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
7683fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7684c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
7685c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
7686c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
7687c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                image->colormap[i].opacity =
768882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    image->colormap[i].opacity > TransparentOpacity/2 ?
768982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                    TransparentOpacity : OpaqueOpacity;
7690c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7691c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7692c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7693c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7694c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
7695e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
7696e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
7697e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
7698c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
7699d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
7700d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
7701d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7702d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7703d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
7704d337164012450d70d62e71cf4a308a29004f7d57glennrp
7705d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
7706d337164012450d70d62e71cf4a308a29004f7d57glennrp
7707d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.red=
77083faa9a3fb01696daaf976d595f492cb530bffb21glennrp            ScaleCharToQuantum(
77093faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.red) & 0xf0) |
77103faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.red) & 0xf0) >> 4);
7711d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.green=
77123faa9a3fb01696daaf976d595f492cb530bffb21glennrp            ScaleCharToQuantum(
77133faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.green) & 0xf0) |
77143faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.green) & 0xf0) >> 4);
7715d337164012450d70d62e71cf4a308a29004f7d57glennrp        image->background_color.blue=
77163faa9a3fb01696daaf976d595f492cb530bffb21glennrp            ScaleCharToQuantum(
77173faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xf0) |
77183faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xf0) >> 4);
7719d337164012450d70d62e71cf4a308a29004f7d57glennrp
7720d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
7721d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7722d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
7723d337164012450d70d62e71cf4a308a29004f7d57glennrp
7724d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
7725d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7726d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
7727d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
7728d337164012450d70d62e71cf4a308a29004f7d57glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7729d337164012450d70d62e71cf4a308a29004f7d57glennrp                exception);
7730d337164012450d70d62e71cf4a308a29004f7d57glennrp
7731d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (r == (PixelPacket *) NULL)
7732d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
7733d337164012450d70d62e71cf4a308a29004f7d57glennrp
7734d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
7735d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
7736d337164012450d70d62e71cf4a308a29004f7d57glennrp              if (r->opacity == TransparentOpacity)
7737d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
7738d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->red = image->background_color.red;
7739d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->green = image->background_color.green;
7740d337164012450d70d62e71cf4a308a29004f7d57glennrp                  r->blue = image->background_color.blue;
7741d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7742d337164012450d70d62e71cf4a308a29004f7d57glennrp              else
7743d337164012450d70d62e71cf4a308a29004f7d57glennrp                {
77443faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->red=ScaleCharToQuantum(
77453faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->red) & 0xf0) |
77463faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->red) & 0xf0) >> 4);
77473faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->green=ScaleCharToQuantum(
77483faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->green) & 0xf0) |
77493faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->green) & 0xf0) >> 4);
77503faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->blue=ScaleCharToQuantum(
77513faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->blue) & 0xf0) |
77523faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->blue) & 0xf0) >> 4);
7753d337164012450d70d62e71cf4a308a29004f7d57glennrp                }
7754d337164012450d70d62e71cf4a308a29004f7d57glennrp              r++;
7755d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
7756d337164012450d70d62e71cf4a308a29004f7d57glennrp
7757d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7758d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
7759d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7760d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7761d337164012450d70d62e71cf4a308a29004f7d57glennrp
7762d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
7763d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
7764d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
7765d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
7766d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7767d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
7768d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
7769d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
77703faa9a3fb01696daaf976d595f492cb530bffb21glennrp            image->colormap[i].red=ScaleCharToQuantum(
77713faa9a3fb01696daaf976d595f492cb530bffb21glennrp                 (ScaleQuantumToChar(image->colormap[i].red) & 0xf0) |
77723faa9a3fb01696daaf976d595f492cb530bffb21glennrp                 (ScaleQuantumToChar(image->colormap[i].red) & 0xf0) >> 4);
77733faa9a3fb01696daaf976d595f492cb530bffb21glennrp            image->colormap[i].green=ScaleCharToQuantum(
77743faa9a3fb01696daaf976d595f492cb530bffb21glennrp                 (ScaleQuantumToChar(image->colormap[i].green) & 0xf0) |
77753faa9a3fb01696daaf976d595f492cb530bffb21glennrp                 (ScaleQuantumToChar(image->colormap[i].green) & 0xf0) >> 4);
77763faa9a3fb01696daaf976d595f492cb530bffb21glennrp            image->colormap[i].blue=ScaleCharToQuantum(
77773faa9a3fb01696daaf976d595f492cb530bffb21glennrp                 (ScaleQuantumToChar(image->colormap[i].blue) & 0xf0) |
77783faa9a3fb01696daaf976d595f492cb530bffb21glennrp                 (ScaleQuantumToChar(image->colormap[i].blue) & 0xf0 >> 4));
7779d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
7780d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7781d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
7782d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
7783d337164012450d70d62e71cf4a308a29004f7d57glennrp
778482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
778582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
778682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
778782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
778882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
778982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
779082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
779182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
779282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.red=
77933faa9a3fb01696daaf976d595f492cb530bffb21glennrp            ScaleCharToQuantum(
77943faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.red) & 0xe0) |
77953faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.red) & 0xe0) >> 3 |
77963faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.red) & 0xc0) >> 6);
779782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.green=
77983faa9a3fb01696daaf976d595f492cb530bffb21glennrp            ScaleCharToQuantum(
77993faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.green) & 0xe0) |
78003faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.green) & 0xe0) >> 3 |
78013faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.green) & 0xc0) >> 6);
780282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        image->background_color.blue=
78033faa9a3fb01696daaf976d595f492cb530bffb21glennrp            ScaleCharToQuantum(
78043faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xe0) |
78053faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xe0) >> 3 |
78063faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 6);
780782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
780882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
780982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7810e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
781182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
781282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
781382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
781482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
781582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
781682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
781782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                exception);
781882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
781982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (r == (PixelPacket *) NULL)
782082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
782182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
782282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
782382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
782482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
782582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
782682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
782782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
782882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
782982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
783082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
783182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
78323faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->red=ScaleCharToQuantum(
78333faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->red) & 0xe0) |
78343faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->red) & 0xe0) >> 3 |
78353faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->red) & 0xc0) >> 6);
78363faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->green=ScaleCharToQuantum(
78373faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->green) & 0xe0) |
78383faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->green) & 0xe0) >> 3 |
78393faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->green) & 0xc0) >> 6);
78403faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->blue=ScaleCharToQuantum(
78413faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->blue) & 0xe0) |
78423faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->blue) & 0xe0) >> 3 |
78433faa9a3fb01696daaf976d595f492cb530bffb21glennrp                       (ScaleQuantumToChar(r->blue) & 0xc0) >> 6);
784482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
784582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r++;
784682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
784782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
784882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
784982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
785082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
785182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
785282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
785382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
785482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
785582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
785682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
785782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7858e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
785982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
786082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
78613faa9a3fb01696daaf976d595f492cb530bffb21glennrp              image->colormap[i].red=ScaleCharToQuantum(
78623faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].red) & 0xe0) |
78633faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].red) & 0xe0) >> 3 |
78643faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].red) & 0xc0) >> 6);
78653faa9a3fb01696daaf976d595f492cb530bffb21glennrp              image->colormap[i].green=ScaleCharToQuantum(
78663faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].green) & 0xe0) |
78673faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].green) & 0xe0) >> 3 |
78683faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].green) & 0xc0) >> 6);
78693faa9a3fb01696daaf976d595f492cb530bffb21glennrp              image->colormap[i].blue=ScaleCharToQuantum(
78703faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].blue) & 0xe0) |
78713faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].blue) & 0xe0) >> 3 |
78723faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 6);
787382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
7874d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
7875d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
787682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
7877c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7878c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors == 0 || image_colors > 256)
7879c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
7880c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7881c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7882c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
7883c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
78843faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
78853faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
78863faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
78873faa9a3fb01696daaf976d595f492cb530bffb21glennrp
78883faa9a3fb01696daaf976d595f492cb530bffb21glennrp        image->background_color.blue=ScaleCharToQuantum(
78893faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xc0) |
78903faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 2 |
78913faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 4 |
78923faa9a3fb01696daaf976d595f492cb530bffb21glennrp            (ScaleQuantumToChar(image->background_color.blue) & 0xc0) >> 6);
7893fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7894c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
7895c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7896e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
7897fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7898c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
7899c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7900c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
7901c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
7902c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
7903c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                exception);
79048d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
7905c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (r == (PixelPacket *) NULL)
7906c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
7907c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
7908c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
7909c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
791082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              if (r->opacity == TransparentOpacity)
791182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
791282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->red = image->background_color.red;
791382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->green = image->background_color.green;
791482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                  r->blue = image->background_color.blue;
791582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
791682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              else
791782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                {
79183faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  r->blue=ScaleCharToQuantum(
79193faa9a3fb01696daaf976d595f492cb530bffb21glennrp                      (ScaleQuantumToChar(r->blue) & 0xc0) |
79203faa9a3fb01696daaf976d595f492cb530bffb21glennrp                      (ScaleQuantumToChar(r->blue) & 0xc0) >> 2 |
79213faa9a3fb01696daaf976d595f492cb530bffb21glennrp                      (ScaleQuantumToChar(r->blue) & 0xc0) >> 4 |
79223faa9a3fb01696daaf976d595f492cb530bffb21glennrp                      (ScaleQuantumToChar(r->blue) & 0xc0) >> 6);
792382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                }
792452a479ca718756af72f96e127f8256499ab68f76glennrp              r++;
7925c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
7926fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7927c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
7928c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
7929c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7930c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
7931c722dd852e8abe407c2846d39662f7ade9c234deglennrp
7932c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
7933c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
7934c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
7935c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
7936c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7937e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
7938c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
7939c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
79403faa9a3fb01696daaf976d595f492cb530bffb21glennrp              image->colormap[i].blue=ScaleCharToQuantum(
79413faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) |
79423faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 2 |
79433faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 4 |
79443faa9a3fb01696daaf976d595f492cb530bffb21glennrp                  (ScaleQuantumToChar(image->colormap[i].blue) & 0xc0) >> 6);
7945c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
7946c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
7947c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
7948c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
7949c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
7950fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
7951fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
7952fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7953fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
7954fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
7955fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
7956fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
79570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
79580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
79590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
79600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      int colortype=mng_info->write_png_colortype;
79610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
79630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
79640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
79660e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
79670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
79688d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
79698d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         mng_info->write_png_colortype != (ssize_t) colortype)
79700e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
79710b206f5daa453dc1035db5890cabc899736dc2d0glennrp
79720e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
79730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
7974fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
7975fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
7976fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
79775a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
79785a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
79795a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
7980fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
79815a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
79825a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
7983fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7984fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
7985fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7986fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
7987fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
7988fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7989fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
7990fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
7991fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
7992fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           ExceptionInfo
7993fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *exception;
7994fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7995fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           register const PixelPacket
7996fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
7997fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7998fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           exception=(&image->exception);
7999fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8000fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8001fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8002fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8003fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8004fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (q == (PixelPacket *) NULL)
8005fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8006fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8007fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8008fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
8009fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 if (q->opacity != TransparentOpacity &&
8010fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->red == ping_trans_color.red &&
8011fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->green == ping_trans_color.green &&
8012fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     (unsigned short) q->blue == ping_trans_color.blue)
8013fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8014fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8015fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8016fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8017fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8018fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 q++;
8019fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8020fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8021fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8022fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8023fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8024fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8025fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8026fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
802767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
802867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
802967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
8030fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
803167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
803267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
803367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
803467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
8035fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
803667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
803767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
8038fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8039fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8040fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8041fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8042fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8043fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8044fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8045fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8046fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8047fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8048fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8049fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8050fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8051fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8052fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8053fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8054fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
80553c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
80563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
80573c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
80583c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8059f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
80603c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
806183c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
80620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
80631273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
80643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
806552a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
806652a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
806752a479ca718756af72f96e127f8256499ab68f76glennrp    {
806852a479ca718756af72f96e127f8256499ab68f76glennrp      image_info=DestroyImageInfo(image_info);
806952a479ca718756af72f96e127f8256499ab68f76glennrp      image=DestroyImage(image);
807015e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp      (void) ThrowMagickException(&IMimage->exception,
807115e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          GetMagickModule(),CoderError,
807215e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
807315e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "`%s'",IMimage->filename);
807452a479ca718756af72f96e127f8256499ab68f76glennrp#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
807552a479ca718756af72f96e127f8256499ab68f76glennrp      UnlockSemaphoreInfo(ping_semaphore);
807652a479ca718756af72f96e127f8256499ab68f76glennrp#endif
807752a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
807852a479ca718756af72f96e127f8256499ab68f76glennrp    }
807952a479ca718756af72f96e127f8256499ab68f76glennrp
80803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
80813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
80823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
80833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
80843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
8085cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8086cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
80870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
80893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
8090cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
80910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
80933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
80943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
80950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
80970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
80983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
80993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
81013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
81023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
8105cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
81063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
81083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
81103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
81113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
81123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
81133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
81143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
81153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
81173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8118cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
81193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8120da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
8121b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8122b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8123b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
81243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
81253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
81273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
81283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
81293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
81303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
81322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
81343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
81353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
81363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
81372b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
81393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
81402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
81422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81434e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
81444e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
81452b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
81463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
81473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
81503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
81510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
81533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
81543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
81550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
81573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
81580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
81603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
81610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
81623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
81633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8165e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
81663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8167e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
81683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8169e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
81703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81718640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
81723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
81738640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
81743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
81758640fb5e9b1094f35f8beab436f81661b8a99448glennrp
81763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
81775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
8178dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
817926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
81803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
818126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
818226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
81833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
81843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
81853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
81860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
8187dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8188dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
81893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
81903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
81913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8192dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8193823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
8194823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->x_resolution+0.5)/2.54);
8195823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
8196823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->y_resolution+0.5)/2.54);
81973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8198dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
81993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
82003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8201dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8202823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution+0.5);
8203823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution+0.5);
82043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8205991d11dd9c33e65872778b81aff1347cd2878154glennrp
82063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
82073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8208dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
8209dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
8210dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
82113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8212991d11dd9c33e65872778b81aff1347cd2878154glennrp
8213823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
8214823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8215823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
8216823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
8217823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
8218991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
82193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
822026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8222a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
822326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
822426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
8225a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
82263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8227a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
8228a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
8229a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
8230a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
8231a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
8232a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
82330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8234a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
8235a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
82360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8237a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
8238a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
82390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8240a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
8241a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
82420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8243a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
8244a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
82450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8246a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
8247a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
82480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8249a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
8250a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
82510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
82520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
82543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
82553b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82563b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
82573b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
82583b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82593b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
82603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
82610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
826326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
82643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
82653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
82663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
82673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
82683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
82693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
82700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82711273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
82723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
82730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8274fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
82750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
82760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
82788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
82798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
82800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
82820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
82830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
82840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
82850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
82870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
82880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
8289f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
82900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
82910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
82920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
82930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
82940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
82950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
82960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
82970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
829867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
82990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
830067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
830167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
830267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
83030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
83043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
83062b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
83078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
83088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
83098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
83105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
831158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
83128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
83130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
83140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
83150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
83160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
83178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
83183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
83208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
83210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83232cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
83248bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
83250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
83270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
83280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
83318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
83320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83331273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
83344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
83351273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
83361273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
83371273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
83381273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
83394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
83404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
83414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
83420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
83444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
83453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
83460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png24)
83483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
83505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
83513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else if (mng_info->write_png32)
83543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
83565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
83573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
83580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
83603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
83615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
83620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
83643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
83660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
83685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
83693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
83702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
83718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
83728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
83737c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
83747c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
83757c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83767c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
83773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
83780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
83797c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
83803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
83813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
83823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
83840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8385d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
83868bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
83870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8388d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
83893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
83913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
83923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8394d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
83953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
83965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
83973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
83983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
83990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84005aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
84015aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
84025aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
84035aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84047c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
84057c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
84067c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
84073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
84085aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
84098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
84105aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84115aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84125aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
84135aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84145aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84160b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84175aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84185aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
84195aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84205aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
84225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
84235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
84245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
84255aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84265aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
84275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
84285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
84300b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
84315aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
84325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
84335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
84345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
84355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
84360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
84375aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
84383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
844126c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
84428640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
844326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
84445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
84450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
84460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
84470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
84480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
84490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
84500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
84513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8452d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
8453d6bf1617e99df0272b231855a933a74e99b6578fglennrp
84545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
84553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
84568d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
84578d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
84583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
84598640fb5e9b1094f35f8beab436f81661b8a99448glennrp
84605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
84613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
846235ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
84635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
84640f111984738842d27d04aed2a3f823d82a943506glennrp
84650f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
84660f111984738842d27d04aed2a3f823d82a943506glennrp           {
84670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
8468c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              (void) ThrowMagickException(&image->exception,
84690f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
8470c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                "image has 0 colors", "`%s'","");
84710f111984738842d27d04aed2a3f823d82a943506glennrp           }
84720f111984738842d27d04aed2a3f823d82a943506glennrp
847335ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
84745af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
8475d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
84763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8477d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
8478d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
8479d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8480d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
84810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8482d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8483d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
8484d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
84850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8486d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
8487d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
84883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
84892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
84905af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
84912b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
84923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
84933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
84943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8495e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
84960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
84973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8498e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
84990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8501e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
85020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
85043c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
85058640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
85068640fb5e9b1094f35f8beab436f81661b8a99448glennrp
85078640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8508e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
85093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
85103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
851158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
85123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
85134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
85144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
85157c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
85167c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
85177c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
85182b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85197c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
85207c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
85217c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
85222b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
85244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
85253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
85264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
85274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
85294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
85304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
8531a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
85324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
85337c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
85347c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
85357c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
85364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
85394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
85411273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp                mask;
85423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
85434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
85440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
85464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
85470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
85494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
85500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85514f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
85524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
85530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
85554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
85560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85574f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
85584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
85590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85604f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
85614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
85620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85634f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
85644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
85650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85664f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
85674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(PixelIntensityToQuantum(
85684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
85690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
85710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85724f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
85734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
85764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85774f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
8578fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
8579fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
8580fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
8581fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
8582fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
85834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85842b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
85854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
85864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
85877c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
85887c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
85890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
85904f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
85914f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
85924f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
85934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
85944f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
85954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
85964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
85974f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
85984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
85994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
86004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
86013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
86023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
86035af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
86045af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
86055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
86065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
86073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
86083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
86093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
86108640fb5e9b1094f35f8beab436f81661b8a99448glennrp
86113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
86120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86132e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
86143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
86150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
861639992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
86173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
86188d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
86198d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
86203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
862135ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
86220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
86249c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
86250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86267c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
86273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
86294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
86303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
86314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
86324f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
86334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
86344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
86354f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
86364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
86374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
86384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
86393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
86400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
86423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
86430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8644a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        if ((image_colors == 0) || ((ssize_t) image_colors-1 > MaxColormapSize))
8645f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
86460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
86485af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
86490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
86513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
86525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
86535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
86543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
86563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
86575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
86580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
865935ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
8660bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
86615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
86623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
86633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
86642b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
86660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
86673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
86683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
86693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
86701a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
86713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
86723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
86733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
86743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
86753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8676bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
86773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
86783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
86793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
86803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
86823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
86833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
86843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
86853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
86863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
86874bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
86883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
86893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
86902b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
86913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
86929c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
86930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
86959c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
86960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
86973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
86989c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
86993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
87025af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
87033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
87060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
87083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
870917a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
871017a1485544c62993fc7a94e343c87fed5f3e6407glennrp
87113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
87123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
87143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
87153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
87165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
87170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
871858e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
87193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
87209c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
87210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87223b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87239c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
87249c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
87253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
87283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8729bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
87303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
87313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
87323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
87333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
87343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
87350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87363b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
87373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
873898156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
8739f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
87400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
874139992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
87423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
8745d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
87463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8747befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
8748befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
8749befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
87505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
8751befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
87520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8753befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                while ((one << ping_bit_depth) < number_colors)
87545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
87553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
87560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
87580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
875958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
87600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
87610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
8762d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
8763d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
87640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
87653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8766d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
8767d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
87683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
87690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
87700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
87710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8772d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
87730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
8774c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
8775c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
8776c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8777c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
8778c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
8779d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
8780d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8781d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
8782d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
8783d6bf1617e99df0272b231855a933a74e99b6578fglennrp                       ping_trans_alpha[i]= (png_byte) (255-
8784d6bf1617e99df0272b231855a933a74e99b6578fglennrp                          ScaleQuantumToChar(image->colormap[i].opacity));
8785d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
87860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
87870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
87883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
87893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
87900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8793c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
87953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
87960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
87994f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
88004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
88014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
88034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
88085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
88095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
88105af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
88115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
88124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
88134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
88144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
88154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
88174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
88184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
88194f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
88204f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
88213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88244383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
88254383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
88262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
88305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
88353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
883635ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
883735ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
883835ef824baa82511126ff0072ae30eee0da9c05a3cristy
883922ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
88403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
884226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
88433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8844a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (QuantumScale*(maxval*(PixelIntensity(&image->background_color))));
88463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88493c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
88503b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
8851991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
885226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
88533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_trans_color.gray=(png_uint_16) (QuantumScale*(maxval*
88555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_trans_color.gray));
88563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
885717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
885826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
885926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
88601273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
886117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
886217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
886317a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
886417a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
886517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
886617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
886717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8868a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
8869a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
887017a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
887117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
887217a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
887317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
88743b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
88750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
88760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
88780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
8879a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
888013d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
8881a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
88820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
88833b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
88843b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
88850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
88860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
88880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
88890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
88900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
88910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
8892a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
889317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
8894d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
88953c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
88963b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
88973b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88983b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
88993c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
89003c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
890117a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
890226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
890317a1485544c62993fc7a94e343c87fed5f3e6407glennrp
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
89073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
89120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
89140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
89170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
89180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
89200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
89240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_mem_level(ping, 9);
89260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
89283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
89290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quality > 9)
89313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
89333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
89343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
89360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression level: %d",level);
89400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_level(ping,level);
89423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Compression strategy: Z_HUFFMAN_ONLY");
89490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_compression_strategy(ping, Z_HUFFMAN_ONLY);
89513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
89543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Setting up filtering");
89563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89572b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
89583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* This became available in libpng-1.0.9.  Output must be a MNG. */
89593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && ((quality % 10) == 7))
89603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
89623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Filter_type: PNG_INTRAPIXEL_DIFFERENCING");
89640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
89663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
89670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Filter_type: 0");
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
89732b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
89743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int
89763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      base_filter;
89773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((quality % 10) > 5)
89798640fb5e9b1094f35f8beab436f81661b8a99448glennrp      base_filter=PNG_ALL_FILTERS;
89800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89818640fb5e9b1094f35f8beab436f81661b8a99448glennrp    else
89828640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if ((quality % 10) != 5)
89833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        base_filter=(int) quality % 10;
89840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89858640fb5e9b1094f35f8beab436f81661b8a99448glennrp      else
89868640fb5e9b1094f35f8beab436f81661b8a99448glennrp        if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
89875af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
89883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (quality < 50))
89898640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_NO_FILTERS;
89900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89918640fb5e9b1094f35f8beab436f81661b8a99448glennrp        else
89928640fb5e9b1094f35f8beab436f81661b8a99448glennrp          base_filter=PNG_ALL_FILTERS;
89930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
89953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
89963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (base_filter == PNG_ALL_FILTERS)
89973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: ADAPTIVE");
89993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
90003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Base filter method: NONE");
90023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
90032b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_filter(ping,PNG_FILTER_TYPE_BASE,base_filter);
90053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9007823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if ((ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse) &&
9008823b55c200d7fc1818ab539b036a9c24feaecda8glennrp     (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
9009c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
9010c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
9011c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
90123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9013c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
90140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9015c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
9016c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
9017c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
9018c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
9019c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
902026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
9021c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
9022c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
9023c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
9024c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
9025e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
9026c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
9027e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
9028e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
9029e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
9030c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
9031c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
903226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
90330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9034c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
90353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9036c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
9037c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
9038cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
9039c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
9040c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
9041c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
9042c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
9043c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
90440b206f5daa453dc1035db5890cabc899736dc2d0glennrp
9045c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
9046c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9047c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
90480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9049c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
9050c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
90513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
90523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
90543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
90563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
90573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
905826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
905926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
906026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
906126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
906226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
906326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
906426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
906526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
90660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
906726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
9068cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
9069cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
90700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
907126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (ping_exclude_gAMA == MagickFalse)
907226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            png_set_gAMA(ping,ping_info,0.45455);
907326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
907526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
90765af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
90773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
90783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90792cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
90802cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
908126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
908226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
90833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
90843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
90863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
90883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
90893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
90923b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
90933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
90943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
909526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
90962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
909726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
90983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
909926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
910026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
910126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
910226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
910326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
910426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
910526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
910626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
910726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
910826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
910926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
911026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
911126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
911226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
911326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
911426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
911526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
911626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
911726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
911826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
911926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
912026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
912126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
912226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
912326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
912426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
91253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9126dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
91275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
91283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
91303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
91313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
91333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9134d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
91353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
91378d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
91395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
91402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
91415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
91425af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
91433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
91440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
91468d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
91475af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91500e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
91510e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
91525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
91533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
91545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
9155991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
91560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
91573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
91593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
91610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
91620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91630e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
91640e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
91650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
91673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
91703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
91715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
91723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91730e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
91753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
91783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
91795af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
91803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
91833bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
91843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
91853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
918758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
91883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
91893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
91903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
91913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
91920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9193b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
9194b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9195b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
91963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
91980e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
9199e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
9200991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
9201c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
9202991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
9203c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
9204c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9205c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
9206c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
9207e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
9208e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
92093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
92123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
92145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
92155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
92165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
92175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
921839992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
921939992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
9220f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
92210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92223b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
922339992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
92248640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
92250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
9226d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
92270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9228d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
9229d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
9233d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
92340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
92350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
92360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9237d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
92380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
92390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
92400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
92410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
92420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
924339992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
924439992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
924539992b4dd9b12ef752d55b8e402c069698851f72glennrp
924626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
924726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
924826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
924926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
925026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
9251991d11dd9c33e65872778b81aff1347cd2878154glennrp
925226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
9253dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
925426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
925526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
925626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
925726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
925826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
925926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
9260823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
9261823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
9262823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
9263823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9264823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
9265823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9266823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
9267823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
9268823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9269823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
9270823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
9271823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9272823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
9273823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
9274823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
927526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9276dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9277dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9278dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
92794f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
9280dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
928126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
928226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
928326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
928426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
9285dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
928626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
928726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
928826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
928926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
929026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
9291dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
9292dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
9293dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
9294da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
9295da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
9296da8f3a7bfddac2680a3069a490db541e7944edafglennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
9297da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
9298da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
9299da8f3a7bfddac2680a3069a490db541e7944edafglennrp
9300da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
9301da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
9302da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
9304991d11dd9c33e65872778b81aff1347cd2878154glennrp
930539992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
9306991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
93073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
93080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
93110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
9312991d11dd9c33e65872778b81aff1347cd2878154glennrp
93130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
93140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
93150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
93160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
93170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
9318991d11dd9c33e65872778b81aff1347cd2878154glennrp
93190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
93200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
93210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
93220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
93230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
93240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
93250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93263b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
93270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
93280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9329c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
93300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
93310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
93320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
93330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
93340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
93350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
9336991d11dd9c33e65872778b81aff1347cd2878154glennrp
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
9338cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
9339da8f3a7bfddac2680a3069a490db541e7944edafglennrp
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
9341991d11dd9c33e65872778b81aff1347cd2878154glennrp
93423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
9343cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
93443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
934526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
93463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
93474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
93484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
934926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
935026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
935126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
935226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
935326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
935426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
935503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
935626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
935726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
935826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
935926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
936026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
936126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
93659c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
93679c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
93683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
93693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
93703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
93723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
93753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
9376b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
9377b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
93787202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9380b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
93813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
9382b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9384b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
9385b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
9386b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9388b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
9390b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9392b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
9393b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93953b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
93963b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9398b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9399b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
94000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9401b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9402e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
94033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9404cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
9405cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
94060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9407cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
94123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
94135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
94173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
94203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
94213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
9425cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
9426cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
94273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9428cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
94293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9430da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
9431b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
9432b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
9433b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
94343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
94353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9436ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
9437ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
9438ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
94403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
94428bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
94448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
94458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
94463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
94478d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
94488d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
94493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
94508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
94513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register const PixelPacket
94523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
94530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
94563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
94583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
94593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
9460bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
94613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9462d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
94633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94643b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
9465a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
94670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (p == (const PixelPacket *) NULL)
94693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
94700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
94723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
94733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9474cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,GrayQuantum,ping_pixels,&image->exception);
94753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
94773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
94783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
9480bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
9481cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
94823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
94833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
94843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
94850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
94873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
94883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9489cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,RedQuantum,ping_pixels,&image->exception);
94903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
94910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
9493bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
9494cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
94953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
94960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94973b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
9498b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9499b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
95000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9501cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
95043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
95073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
95110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
95133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
95140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
95153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
951658e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
95175af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
95188d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
95193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
95220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
95243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9526bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
95273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
95292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (p == (const PixelPacket *) NULL)
95313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
95322cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
95358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
95363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9537cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,GrayQuantum,ping_pixels,&image->exception);
95382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9541cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RedQuantum,ping_pixels,&image->exception);
95422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
95448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
95472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
9549b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
95503b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9551b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95528bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
95532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95548bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9555cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
9556b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
95572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95583b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
9559b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95608bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
95612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9562cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
95633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95642cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
95668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
95678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
95688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
95698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
95708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
95718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
95728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
95730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
95753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
95768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          register const PixelPacket
95778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
95780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
95828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
95838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
95848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
95858bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
9586b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
95878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
95888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
95892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
95918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
95922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
95948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
95958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
95968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9597cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,RedQuantum,ping_pixels,&image->exception);
95982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
96008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9601cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,GrayQuantum,ping_pixels,&image->exception);
96028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96032cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9607cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
96088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
96092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
96118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
96138bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
96168bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9617cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBAQuantum,ping_pixels,&image->exception);
96182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
96208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9621cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBQuantum,ping_pixels,&image->exception);
96222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96233b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
9624b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
96262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9627cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
9628b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
96298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96302cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
96328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
96338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
96348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
96358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
96368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
96378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
96388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
96398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
96408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
96422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
96448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
96458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
96462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
96488640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
96498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
96508bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96518bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
96522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9653770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
9654770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                   &image->exception);
96552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (p == (const PixelPacket *) NULL)
96578bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
96582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96598bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
966044757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
96614bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
96624bf89731a90c6e03598950223e19e7be7b95d630glennrp
966344757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9664cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                       quantum_info,GrayQuantum,ping_pixels,&image->exception);
966544757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
96662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
96688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
96698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
96708bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96718bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
96722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
9674cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
9675d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
96768bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
96772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
96798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
9680179d075d718a6da568c3600b7e6b159b8a293b41glennrp                    (void) ExportQuantumPixels(image,(const CacheView *) NULL,
96815eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      quantum_info,IndexQuantum,ping_pixels,&image->exception);
96822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96835eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
96845eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
96855eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96861a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
96875eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
96885eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96895eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
96905eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
96915eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
96928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
9693cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
96948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
96958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
96962cc891a179d622dde7bbb8854138851e828bc6eaglennrp
96978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
96988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
96998bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
97008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
97018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
97028640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
97043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97058bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
97068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
9707b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
9708b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
97093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
97113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9713b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
97140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9716e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
97170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9719e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
97200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
97223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
97253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97285af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
97290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
97313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
97343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
97350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97375af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
97380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
97413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9743a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9745823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
97463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
974726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
974826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
974926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
975026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
975126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
975226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
97532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
975426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
9755a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
9756a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      /* Don't write any "png:" properties; those are just for "identify" */
9757a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(property,"png:",4) != 0 &&
9758a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
9759a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
9760a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
9761823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
9762a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
9763a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
9764a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
9765a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
9766a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
976726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
9768c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
9769c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
9770c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
9771c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
9772c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
9773c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
97742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9775c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
9776c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
97772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9778c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
9779c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
97802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9781c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
978226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
9783c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
9784c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
9785c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
9786c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
978726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
97882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
9789c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
9790c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
9791c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9792c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
9793c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9794c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9795c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
9796c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
9797c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
9798c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
9799c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
9800c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
980126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
980226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
980326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
98043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
98053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
9807cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
98083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
98120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
98140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
98163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
98185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
98195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
98203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
98223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
98233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
98263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
98283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
982903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
98303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
98383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
98393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
98405af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
98413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
98423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
98435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
98443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
98453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
98463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
98473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
98483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
98490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
98513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
98523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
98533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
9855c70af4ac292f8db9a1ab488318912894d412cb8cglennrp     (void) ThrowMagickException(&image->exception,GetMagickModule(),
98563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
9857c70af4ac292f8db9a1ab488318912894d412cb8cglennrp       "`%s'",image->filename);
98580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
98603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
98613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
98625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9865cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
9868cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9871da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (ping_have_blob != MagickFalse)
9872b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
9873b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9874b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
9875b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
9876b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9877b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
9878b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
9879b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
9880b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
9881b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
9882b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
98833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
98843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
98860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
98873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
98883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
98893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
98903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
98923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
98973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
98993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
99003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
99033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
99043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
99063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
99143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
99203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
99223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
99243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99255a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
99265a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
99273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
99295a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
99305a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
9931e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
9932e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               3-3-3-1, or  3-3-2-1 palette.
9933e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
9934e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
9935e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
99365a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
99375a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
99395a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
99405a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
99415a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
99423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
99443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
99455a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
99465a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
99475a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
99485a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
99495a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
99533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
99540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
99555a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
99565a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
99593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
9961bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
9962bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
9963bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
99723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
99743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
99753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
99793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
99803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99815a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
99825a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
99835a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
99845a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
99853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
99863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
99873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
99885a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
99895a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%   or transparency limitations.
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
999197cefe2cb8fecfc09dae478af3cd9e05b07a5926glennrp%  To do: Enforce the previous paragraph.
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
99943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
99953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
99963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
99973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
99983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
99993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
100003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
100013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
100033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
100053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
10006bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
10007bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
100083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
100103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
100113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
10012bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
100133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10014bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
100153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
100163241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
100170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
10018d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
100190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
100200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
100210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
10022cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
100230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
10024d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
10025d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
10026d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
10027d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
10028d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
10029d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
10030d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
100310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
100323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
100343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
100353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *image)
100363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
100373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1003821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1003921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1004021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
100413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
100423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
100443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
100453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
100473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
100483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1005021f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
100515c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
100525c7cf4e469a4dad7e277783749155932252c52dfglennrp
100533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
100553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
100573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
100583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
100593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
100603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10061fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
100623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
100643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1006673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
100670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
100693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
100700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
100723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
100733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
100743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
100753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
10076a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
100773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
100783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
100803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
100823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
100833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
100843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
100863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100879c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
100889c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
100899c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
100903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
100913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
100923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
100933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
100949c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
100959c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
100969c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
100970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100989c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
100999c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
101000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101019c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
101029c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
101030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101049c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
101053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
101083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101099c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
101109c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
101119c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
101120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101139c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
101149c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
101150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101169c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
101179c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
101180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101199c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
101203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
101238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
101243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
101279c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
101280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101309c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
101310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101339c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
101340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
101369c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
101370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
101399c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
101400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10141bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10142bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10143bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10144bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
10145bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10146bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101489c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10149bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
101503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
101530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
101553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
101573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
101589c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
101590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
101619c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
101620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
101649c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
101650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
101679c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
101680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
101709c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
101710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10172bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10173bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10174bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10175bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
10176bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10177bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
101783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
101799c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10180d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
101813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
101840e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101850dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
101860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
101870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
101890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
101900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
101910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
101920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
101930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
101950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
101960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
101970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
101980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
101990dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
102000dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
102010dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
102020dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * appear in the "include-chunk" list.
102030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
102050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
102060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
102070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
102090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
102100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
102110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
102130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
102140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
102150e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
102160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * artifact to "none,gama".
102170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
102180e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1021926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1022026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
10221a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1022226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1022326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1022426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1022526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1022626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1022726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1022826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1022926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
10230a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1023126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1023226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1023326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1023426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
102358d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
102368d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
102378d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  value=GetImageArtifact(image,"png:preserve-colormap");
102388d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
102398d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     value=GetImageOption(image_info,"png:preserve-colormap");
102408d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
102418d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
102428d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
1024303812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1024403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
102455c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
102465c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
102475c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10248acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102495c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
10250acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10251acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10252acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
10253acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
102545c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10255acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
102565c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1025726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10258acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10259acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
10260acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10261acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1026203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1026303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1026426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1026503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1026603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1026726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1026803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1026926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1027003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
102712cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
102722cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
102732cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102742cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
102752cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
102762cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102772cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
102782cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1027903812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1028003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1028103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1028203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1028303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1028403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1028503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1028603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1028703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1028803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
10289a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
1029003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1029103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1029203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1029303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1029403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1029503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1029603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1029703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
10298a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1029903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1030003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1030103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1030203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1030303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
103042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1030503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1030603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1030703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1030803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
10309a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
1031003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1031103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1031203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1031303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1031403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1031503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1031603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1031703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
10318a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1031903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1032003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1032103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1032203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
103232cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1032403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1032503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
103262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1032703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1032803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
103292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10330a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
10331a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
10332a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1033303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1033403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
103352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1033703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1033903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1034003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
103412cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1034303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1034403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1034503812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
103462cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1034703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1034803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
103492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1035103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
103522cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1035403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
103552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10356a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10357a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
103582cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1035903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1036003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
103612cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10362a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10363a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
10364a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1036503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1036603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
103672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1036803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1036903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
103702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1037103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1037203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
103732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1037403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10375ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1037626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1037726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
103785c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
103795c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
103805c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
10381acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103825c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
10383acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
10384acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10385acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
10386acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
103875c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
10388acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
103895c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1039026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10391acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
10392acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
10393acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
10394acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1039503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1039603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1039703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1039803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1039926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1040003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1040126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1040203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
104032cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
104042cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
104052cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104062cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
104072cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
104082cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104092cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
104102cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1041103812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1041203812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1041303812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1041403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1041503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1041603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1041703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1041803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1041903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
10420a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickFalse;
1042103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1042203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1042303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1042403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1042503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1042603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1042703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1042803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
10429a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1043003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1043103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1043203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1043303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1043403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104352cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1043603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1043703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1043803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1043903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
10440a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickTrue;
1044103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1044203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1044303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1044403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1044503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1044603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1044703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1044803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
10449a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1045003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1045103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1045203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1045303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
104542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1045603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
104572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1045803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1045903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
104602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10461a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
10462a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
10463a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1046403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1046503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
104662cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1046703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1046803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104692cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1047103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
104722cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1047403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1047503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1047603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
104772cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1047803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1047903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
104802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1048103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1048203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
104832cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1048403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1048503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
104862cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10487a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
10488a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
104892cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1049003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1049103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
104922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10493a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
10494a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
10495a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1049603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1049703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
104982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1049903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1050003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
105012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1050203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1050303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
105042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1050503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
10506ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1050726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1050826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1050903812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1051026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1051126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
1051326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1051426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1051626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1051726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1051826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
10519a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
10520a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10521a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1052226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1052326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1052526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1052626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1052726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1052826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1052926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1053126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1053226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1053326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1053526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1053626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1053726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1053826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1053926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1054026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1054226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1054526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1054626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1054726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
10548a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
10549a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10550a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1055126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1055226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1055426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1055526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1055726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1055826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1055926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1056026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1056126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
10562b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
105633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10564b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
105653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
105670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
105700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
105723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
105733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
105753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
105773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
105783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
105793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
105803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
105813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
105823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
105843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
105853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1058703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
105883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
105893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
105913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
105923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
105943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
105953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
105963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
105973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
105993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
106033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10604bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
10608fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
106153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
106253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
106330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
106363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image_info for opacity.");
106380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
106400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
106453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
106470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
106490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
106513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
106520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
106543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=SeparateImageChannel(jpeg_image,OpacityChannel);
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      status=NegateImage(jpeg_image,MagickFalse);
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
106570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
106600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
106630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
106673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,
106683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
106693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
106723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
106743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
106753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
106763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
106773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale PNG blob */
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
107063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Encode opacity as a grayscale JPEG blob */
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
107143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
107153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
10719f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
107210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10724e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
10725e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
107283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
107293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
107303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
107313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
107323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
107353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
107363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1073703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
107384e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
107394e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
107403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
107413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
107423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
107463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
107473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
107483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
107493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
107503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10753f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
107540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10756f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
107570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
107600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
107630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
107660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
107690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
107720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
107750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
107780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
107823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
10784cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
107853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
107893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10801bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
108053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
108063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
10808bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1081003812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
108113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
108133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
108153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
108163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
108173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
108183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
108193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
108203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
108213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
108223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
108233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
108253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
108283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
108303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1083103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
108320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
10834e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10835cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10836e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
108370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
10839e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
10840cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
10841e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
108420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
108493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1085503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1085635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
108653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
108663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
108693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1087203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1087435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1087535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1087735ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1087835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1088035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1088135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1088335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1088435ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
108863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
108873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
108883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
108933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
108943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
108953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
108963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1089703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
108983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
108993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1090035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
109013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
109020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1090335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
109050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
109103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
109113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
109123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1091335ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
109143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
109150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1091635ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
109173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
109180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1092435ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1092535ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
109263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
109273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
109293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
109303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
109363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
109383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
109393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1094003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
10941bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
10942bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
109433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
109443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
109453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
109483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
109503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1095103812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
109523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
109573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
109613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
109633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10964bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
109663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10967bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
109693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
109713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
109723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10973e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
10974f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
109753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
109783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
10979bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
109823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
109830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
109853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
10987bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1098803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
109893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
109903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
109913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
109923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
109930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
109953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
109963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
109973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10998e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
10999e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
110003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
110013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
110023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
110033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
110053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
110063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
110073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
110083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11009e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
11010bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
110113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1101203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
110133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
110143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
110153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
110163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
110173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
110183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
110193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
110203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
110233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
110263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
110273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
110283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
110333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
110353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
110363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
110373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
110403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) FormatMagickString(jpeg_image_info->filename,MaxTextExtent,"%s",
110413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
110423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
110443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
110453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11048e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
11049e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
110503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
110523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
110530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
110553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
110563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
110570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
110610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
110630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
110663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11067e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
11068e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
110693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11071e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
110723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
110730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
110743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
11075bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
110763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1107703812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
110783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
110803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
110813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
110833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
110843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
110853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
110863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
11088cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
110893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
110913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
110923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1109303812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
110943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
110953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
110963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
110973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
110983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
110993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
111000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
111013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
111023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
111033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
111063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
111113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
111173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
111193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
111213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
111233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
111253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
111273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
111293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
111303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
111323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image)
111333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1113521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1113603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
111373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
111403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
111413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
111443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
111463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
111473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
111483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
111493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11150fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
111513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
111523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
111533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
111543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
111573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1115973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
111603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
111613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
111623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
111633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
111643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
111653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
111663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
111673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
111683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
111703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
111723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
111733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
111753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
111763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
111773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
111783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
111793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
111803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
111813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111843ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
111853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
111863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
111873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
111883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
111903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
111913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
111923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1119321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
111943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
111953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1119603812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1119703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1119803812ae402fb53d548f0e1d7d14720768f803c2dglennrp
111993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
112003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
112013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
112033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
112043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
112053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
112063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
112083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
112093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
112103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
112113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
112133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
112143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
112153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11216bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
112173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
112183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
112203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
112213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
112233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
112243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
112253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11226bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
112273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
112283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
112303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
112313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
112323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11233d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
112343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
112353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
112363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
112373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
112383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
112413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
112433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
112443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
112453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
112463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
11247fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
112483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
112493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
112503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
112513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
112543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1125673bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
112573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
112583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
112593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
112613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
112623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
112633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
112643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
112653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
112663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
112683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
112693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
112703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
112723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
112733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
112743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
112753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
112763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
112773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
112793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
112803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
112813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
112833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
112843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
112853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
112873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
112883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
112903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
112913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
112923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
112933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
112943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
112953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
112963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
112970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
112983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11299e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
113000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
113033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
113053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
113063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
113073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11308e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
113090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11311e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
113120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
113143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
113160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
113200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
113223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
113240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
113280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
113303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11331e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
113320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
113343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
113360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
113373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
113383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
113393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
113403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
113413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
113433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
113443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
113453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
113463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
113483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
113493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
113503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
113513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
113543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
113553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
113563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
113573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
113583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
113593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
113603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
113613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
113623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
113633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
113643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
113653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
113663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
113683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
113693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
113703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
113713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
113723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
113733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
113743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
113753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
113763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
113773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
113783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
113793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
113803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
113813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
113823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
113833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
113843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
113853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
113863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
113873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
113883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
113893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
113903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
113913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
113923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
113933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
113943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
113953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
113963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
113973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
113983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
113990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
114013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
114023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
114053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
114060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
114083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
114090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
114113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
114123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
114133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
114143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
114150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
114173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
114180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
114200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
114223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
114233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
114240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
114263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
114273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
114283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
114293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
114303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
114313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
114320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
114343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
114363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
114373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
114383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
114393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
114403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
114413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
114433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
114443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
114453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
114463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
114473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
114483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
114493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
114503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
114513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
114520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
114543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
114550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
114573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
114583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
114590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
114613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
114623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
114633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
114640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
114663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
114673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
114683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
114693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
114703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
114713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
114723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
114733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
114743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
114753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
114763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
114773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
114783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
114793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
114803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
114813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
114823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
114833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
114853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
114883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
114913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
115020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
115083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
115093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
115103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
115123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
115133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
115143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
115153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
115160261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
11517d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
11518d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
11519d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
11520d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
11521d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
11522d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
11523d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
115243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
115253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
115273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
11529cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
11530cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
115313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
115330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
115353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
115360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
115383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
115390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
115413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
115483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
115493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
115513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
115523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
115533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
115553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
115563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
115573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
115583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
115593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1156003812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
115614e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
115624e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
115633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
115643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
115653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
115663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
115673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
115730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
115763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
115793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
115820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
115853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
115870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
115893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
115903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
115923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
115940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
115963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
115973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
115980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
116003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
116030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
116053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
116063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
116093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
116103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
116123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
116143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
11621bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1162203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
116233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
116243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
116283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
116293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
116303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
116333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1163603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
116373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
116383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
116393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
116403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
116410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
116433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
116440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
116463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
116470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
116493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11651e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
11652e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
116530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
116553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11656e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
116570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11660e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
116623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
116633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
116643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
116673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
116683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
116693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
116703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
116723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
116733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
116753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1167603812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
116770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
11679e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11680cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11681e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
116820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
11684e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
11685cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
11686cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
116870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
116893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
116913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
116920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
116943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
116953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
116973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
116983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
116993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
117003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
117013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1170203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1170335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
117043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
117053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
117063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
117073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
117093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
117113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
117123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
117143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
117153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
117173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1171803812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
117193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1172035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1172135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
117223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1172335ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1172435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
117253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1172635ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1172735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
117283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1172935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1173035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
117313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
117323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
117333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
117343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
117373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
117393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
117403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
117413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
117423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1174303812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
117440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
117463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1174735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
117490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1175035ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
117513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
117520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
117543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
117573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
117593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1176035ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
117613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
117620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1176335ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
117643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
117650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
117673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1177135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1177235ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
117743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
117803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
117813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
117833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
117843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
117853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1179103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
117973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
117993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
118003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
118013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
118023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
118033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1180403812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
118053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
118063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
118073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
118083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
118093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
118123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
118143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
11815bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
118163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
118173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
118193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
118223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1182403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
118250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11826bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
118273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
118283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
118293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
118303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
118320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
118343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
118363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
118403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
118413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
118443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
118463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
118483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
118503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
118513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
118533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
118563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
118573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
118583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
118593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
118603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
118613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
118623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
118653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
118663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
118673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
118683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
118693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
11870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
118723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
118743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1187603812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
118770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11878bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
118793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
118803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
118813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
118833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
118840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
118863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
118893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
118923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
118963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11897bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
118983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
118993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
119043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
119053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
119073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
119093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
119103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
119123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
119133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
119143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1191703812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
119183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
119193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
119223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
119233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
119243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
119333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
119343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
119373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1194603812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
119493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
119503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
119523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
119533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
119543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
119553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
119563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
119573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1195803812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
119603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
119613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
119623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
119633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
119643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
119653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
119663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
119673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
119704e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
119723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
119733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
119863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
119873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
119883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
119893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
119903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
119913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
119923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
119933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
119943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
119962f2e514554975d510c88df54de98c6cdc1080f1cglennrp
11997b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
119988d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
119992f2e514554975d510c88df54de98c6cdc1080f1cglennrp
120002f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
120012f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
120022f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
12003a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
120042f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
120052f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
120062f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
120072f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
120082f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
120092f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
120102f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
120112f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
12012a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
120132f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
120142f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
120152f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
120162f2e514554975d510c88df54de98c6cdc1080f1cglennrp
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
120183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
120243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
120253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
120263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
120293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
120313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
120320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
120343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
120350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
120370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
120403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
120433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
120443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
120463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1204703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
120483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
120493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
120503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
120513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
120533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
120553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
120560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
120590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
120613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12062d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1206339992b4dd9b12ef752d55b8e402c069698851f72glennrp
120643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
120653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
120673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
120683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
120690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
120713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
120723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1207339992b4dd9b12ef752d55b8e402c069698851f72glennrp
120743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
120753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
120773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12078d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
120793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12080