png.c revision 8723e4bcd840478cecfd29891e792edb499cd0e9
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*/
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/artifact.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h"
54510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/enhance.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/histogram.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/layer.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h"
664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/MagickCore.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h"
694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h"
724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel.h"
734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/profile.h"
754c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h"
764c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
774c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h"
784c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/semaphore.h"
794c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
804c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
814c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h"
824c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
834c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string-private.h"
844c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/transform.h"
854c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h"
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
87286a6355c4544b794da2b6df973faad07c69e541glennrp
887ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp/* Suppress libpng pedantic warnings that were added in
897ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * libpng-1.2.41 and libpng-1.4.0.  If you are working on
90faa852bad40107edae19405e76a299057668d795glennrp * migration to libpng-1.5, remove these defines and then
917ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp * fix any code that generates warnings.
927ef138c2e0e2bd4acefd810968b0324f6dc469f1glennrp */
93991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp/* #define PNG_DEPRECATED   Use of this function is deprecated */
94faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_USE_RESULT   The result of this function must be checked */
95faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_NORETURN     This function does not return */
96faa852bad40107edae19405e76a299057668d795glennrp/* #define PNG_ALLOCATED    The result of the function is new memory */
978371ecc013ff231ce380d8717e517312e62e1f01glennrp/* #define PNG_DEPSTRUCT    Access to this struct member is deprecated */
985b927348e949d94f3a64b055eccb03459f115c69glennrp
995b927348e949d94f3a64b055eccb03459f115c69glennrp/* PNG_PTR_NORETURN does not work on some platforms, in libpng-1.5.x */
10075cfe702843fd25dba7cb241c05fa65957c67129cristy#define PNG_PTR_NORETURN
101286a6355c4544b794da2b6df973faad07c69e541glennrp
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "png.h"
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "zlib.h"
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* ImageMagick differences */
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define first_scene scene
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Optional declarations. Define or undefine them as you like.
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* #define PNG_DEBUG -- turning this on breaks VisualC compiling */
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Features under construction.  Define these to work on them.
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_OBJECT_BUFFERS
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_BASI_SUPPORTED
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_COALESCE_LAYERS /* In 5.4.4, this interfered with MMAP'ed files. */
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_INSERT_LAYERS   /* Troublesome, but seem to work as of 5.4.4 */
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_JPEG_DELEGATE)
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  define JNG_SUPPORTED /* Not finished as of 5.5.2.  See "To do" comments. */
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(RGBColorMatchExact)
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IsPNGColorEqual(color,target) \
1268e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp       (((color).red == (target).red) && \
1278e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).green == (target).green) && \
1288e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp        ((color).blue == (target).blue))
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1318e58efdecda887b08ef730d68290a61081ef2566glennrp/* Macros for left-bit-replication to ensure that pixels
1328e58efdecda887b08ef730d68290a61081ef2566glennrp * and PixelPackets all have the image->depth, and for use
1338e58efdecda887b08ef730d68290a61081ef2566glennrp * in PNG8 quantization.
1348e58efdecda887b08ef730d68290a61081ef2566glennrp */
1358e58efdecda887b08ef730d68290a61081ef2566glennrp
1368e58efdecda887b08ef730d68290a61081ef2566glennrp
1378e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR01: Replicate top bit */
1388e58efdecda887b08ef730d68290a61081ef2566glennrp
13905001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR01PacketRed(pixelpacket) \
1408e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=(ScaleQuantumToChar((pixelpacket).red) < 0x10 ? \
1418e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1428e58efdecda887b08ef730d68290a61081ef2566glennrp
14391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketGreen(pixelpacket) \
1448e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=(ScaleQuantumToChar((pixelpacket).green) < 0x10 ? \
1458e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1468e58efdecda887b08ef730d68290a61081ef2566glennrp
14791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketBlue(pixelpacket) \
1488e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=(ScaleQuantumToChar((pixelpacket).blue) < 0x10 ? \
1498e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1508e58efdecda887b08ef730d68290a61081ef2566glennrp
1514c08aed51c5899665ade97263692328eea4af106cristy#define LBR01PacketAlpha(pixelpacket) \
1524c08aed51c5899665ade97263692328eea4af106cristy     (pixelpacket).alpha=(ScaleQuantumToChar((pixelpacket).alpha) < 0x10 ? \
1538e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1548e58efdecda887b08ef730d68290a61081ef2566glennrp
15591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGB(pixelpacket) \
156bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
15705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR01PacketRed((pixelpacket)); \
15891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketGreen((pixelpacket)); \
15991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketBlue((pixelpacket)); \
160bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1618e58efdecda887b08ef730d68290a61081ef2566glennrp
16291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR01PacketRGBO(pixelpacket) \
163bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
16491d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR01PacketRGB((pixelpacket)); \
1654c08aed51c5899665ade97263692328eea4af106cristy        LBR01PacketAlpha((pixelpacket)); \
166bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1678e58efdecda887b08ef730d68290a61081ef2566glennrp
168ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR01PixelRed(pixel) \
1694c08aed51c5899665ade97263692328eea4af106cristy        (ScaleQuantumToChar(GetPixelRed(image,(pixel))) < 0x10 ? \
1708e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1718e58efdecda887b08ef730d68290a61081ef2566glennrp
17254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelGreen(pixel) \
1734c08aed51c5899665ade97263692328eea4af106cristy        (ScaleQuantumToChar(GetPixelGreen(image,(pixel))) < 0x10 ? \
1748e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1758e58efdecda887b08ef730d68290a61081ef2566glennrp
17654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelBlue(pixel) \
1774c08aed51c5899665ade97263692328eea4af106cristy        (ScaleQuantumToChar(GetPixelBlue(image,(pixel))) < 0x10 ? \
1788e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1798e58efdecda887b08ef730d68290a61081ef2566glennrp
18054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelAlpha(pixel) \
1814c08aed51c5899665ade97263692328eea4af106cristy        (ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) < 0x10 ? \
1828e58efdecda887b08ef730d68290a61081ef2566glennrp        0 : QuantumRange);
1838e58efdecda887b08ef730d68290a61081ef2566glennrp
18454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGB(pixel) \
185bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
186ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR01PixelRed((pixel)); \
18754cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelGreen((pixel)); \
18854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelBlue((pixel)); \
189bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1908e58efdecda887b08ef730d68290a61081ef2566glennrp
19154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR01PixelRGBA(pixel) \
192bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
19354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelRGB((pixel)); \
19454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR01PixelAlpha((pixel)); \
195bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
1968e58efdecda887b08ef730d68290a61081ef2566glennrp
1978e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR02: Replicate top 2 bits */
1988e58efdecda887b08ef730d68290a61081ef2566glennrp
19905001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR02PacketRed(pixelpacket) \
2008e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2018e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xc0; \
2028e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2038e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2048e58efdecda887b08ef730d68290a61081ef2566glennrp   }
20591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketGreen(pixelpacket) \
2068e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2078e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xc0; \
2088e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2098e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2108e58efdecda887b08ef730d68290a61081ef2566glennrp   }
21191d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketBlue(pixelpacket) \
2128e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2138e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xc0; \
2148e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
2158e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2168e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2174c08aed51c5899665ade97263692328eea4af106cristy#define LBR02PacketAlpha(pixelpacket) \
2188e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2194c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xc0; \
2204c08aed51c5899665ade97263692328eea4af106cristy     (pixelpacket).alpha=ScaleCharToQuantum( \
2218e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))); \
2228e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2238e58efdecda887b08ef730d68290a61081ef2566glennrp
22491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGB(pixelpacket) \
225bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
22605001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR02PacketRed((pixelpacket)); \
22791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketGreen((pixelpacket)); \
22891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue((pixelpacket)); \
229bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2308e58efdecda887b08ef730d68290a61081ef2566glennrp
23191d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR02PacketRGBO(pixelpacket) \
232bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
23391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketRGB((pixelpacket)); \
2344c08aed51c5899665ade97263692328eea4af106cristy        LBR02PacketAlpha((pixelpacket)); \
235bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2368e58efdecda887b08ef730d68290a61081ef2566glennrp
237ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR02PixelRed(pixel) \
2388e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2394c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
2408e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
2414c08aed51c5899665ade97263692328eea4af106cristy     SetPixelRed(image, ScaleCharToQuantum( \
242847370c32c6b67817205f49897c43c540fd670c4glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
243847370c32c6b67817205f49897c43c540fd670c4glennrp       (pixel)); \
2448e58efdecda887b08ef730d68290a61081ef2566glennrp   }
24554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelGreen(pixel) \
2468e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2474c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
2488e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xc0; \
2494c08aed51c5899665ade97263692328eea4af106cristy     SetPixelGreen(image, ScaleCharToQuantum( \
250847370c32c6b67817205f49897c43c540fd670c4glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
251847370c32c6b67817205f49897c43c540fd670c4glennrp       (pixel)); \
2528e58efdecda887b08ef730d68290a61081ef2566glennrp   }
25354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelBlue(pixel) \
2548e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2558e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
2564c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xc0; \
2574c08aed51c5899665ade97263692328eea4af106cristy     SetPixelBlue(image, ScaleCharToQuantum( \
258847370c32c6b67817205f49897c43c540fd670c4glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
259847370c32c6b67817205f49897c43c540fd670c4glennrp       (pixel)); \
2608e58efdecda887b08ef730d68290a61081ef2566glennrp   }
26154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelAlpha(pixel) \
2628e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2638e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
2644c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xc0; \
2654c08aed51c5899665ade97263692328eea4af106cristy     SetPixelAlpha(image, ScaleCharToQuantum( \
266847370c32c6b67817205f49897c43c540fd670c4glennrp       (lbr_bits | (lbr_bits >> 2) | (lbr_bits >> 4) | (lbr_bits >> 6))), \
267847370c32c6b67817205f49897c43c540fd670c4glennrp       (pixel) ); \
2688e58efdecda887b08ef730d68290a61081ef2566glennrp   }
2698e58efdecda887b08ef730d68290a61081ef2566glennrp
27054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGB(pixel) \
271bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
272ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR02PixelRed((pixel)); \
27354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelGreen((pixel)); \
27454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelBlue((pixel)); \
275bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2768e58efdecda887b08ef730d68290a61081ef2566glennrp
27754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR02PixelRGBA(pixel) \
278bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
27954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelRGB((pixel)); \
28054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR02PixelAlpha((pixel)); \
281bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
2828e58efdecda887b08ef730d68290a61081ef2566glennrp
2838e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR03: Replicate top 3 bits (only used with opaque pixels during
2848e58efdecda887b08ef730d68290a61081ef2566glennrp   PNG8 quantization) */
2858e58efdecda887b08ef730d68290a61081ef2566glennrp
28605001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR03PacketRed(pixelpacket) \
2878e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2888e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xe0; \
2898e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum( \
2908e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2918e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketGreen(pixelpacket) \
2938e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
2948e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xe0; \
2958e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum( \
2968e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
2978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
29891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketBlue(pixelpacket) \
2998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xe0; \
3018e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum( \
3028e58efdecda887b08ef730d68290a61081ef2566glennrp       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))); \
3038e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3048e58efdecda887b08ef730d68290a61081ef2566glennrp
30591d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR03PacketRGB(pixelpacket) \
306bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
30705001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR03PacketRed((pixelpacket)); \
30891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketGreen((pixelpacket)); \
30991d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketBlue((pixelpacket)); \
310bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3118e58efdecda887b08ef730d68290a61081ef2566glennrp
312ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR03PixelRed(pixel) \
3138e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3144c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3158e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
3164c08aed51c5899665ade97263692328eea4af106cristy     SetPixelRed(image, ScaleCharToQuantum( \
3174c08aed51c5899665ade97263692328eea4af106cristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3188e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3194c08aed51c5899665ade97263692328eea4af106cristy#define LBR03Green(pixel) \
3208e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3214c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3228e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
3234c08aed51c5899665ade97263692328eea4af106cristy     SetPixelGreen(image, ScaleCharToQuantum( \
3244c08aed51c5899665ade97263692328eea4af106cristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3258e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3264c08aed51c5899665ade97263692328eea4af106cristy#define LBR03Blue(pixel) \
3278e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3284c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelBlue(image,(pixel))) \
3298e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xe0; \
3304c08aed51c5899665ade97263692328eea4af106cristy     SetPixelBlue(image, ScaleCharToQuantum( \
3314c08aed51c5899665ade97263692328eea4af106cristy       (lbr_bits | (lbr_bits >> 3) | (lbr_bits >> 6))), (pixel)); \
3328e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3338e58efdecda887b08ef730d68290a61081ef2566glennrp
3344c08aed51c5899665ade97263692328eea4af106cristy#define LBR03RGB(pixel) \
335bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
336ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR03PixelRed((pixel)); \
3374c08aed51c5899665ade97263692328eea4af106cristy        LBR03Green((pixel)); \
3384c08aed51c5899665ade97263692328eea4af106cristy        LBR03Blue((pixel)); \
339bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3408e58efdecda887b08ef730d68290a61081ef2566glennrp
3418e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR04: Replicate top 4 bits */
3428e58efdecda887b08ef730d68290a61081ef2566glennrp
34305001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR04PacketRed(pixelpacket) \
3448e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3458e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red) & 0xf0; \
3468e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3478e58efdecda887b08ef730d68290a61081ef2566glennrp   }
34891d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketGreen(pixelpacket) \
3498e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3508e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green) & 0xf0; \
3518e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3528e58efdecda887b08ef730d68290a61081ef2566glennrp   }
35391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketBlue(pixelpacket) \
3548e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3558e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue) & 0xf0; \
3568e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3578e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3584c08aed51c5899665ade97263692328eea4af106cristy#define LBR04PacketAlpha(pixelpacket) \
3598e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3604c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha) & 0xf0; \
3614c08aed51c5899665ade97263692328eea4af106cristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))); \
3628e58efdecda887b08ef730d68290a61081ef2566glennrp   }
3638e58efdecda887b08ef730d68290a61081ef2566glennrp
36491d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGB(pixelpacket) \
365bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
36605001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR04PacketRed((pixelpacket)); \
36791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketGreen((pixelpacket)); \
36891d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketBlue((pixelpacket)); \
369bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3708e58efdecda887b08ef730d68290a61081ef2566glennrp
37191d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR04PacketRGBO(pixelpacket) \
372bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
37391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB((pixelpacket)); \
3744c08aed51c5899665ade97263692328eea4af106cristy        LBR04PacketAlpha((pixelpacket)); \
375bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
3768e58efdecda887b08ef730d68290a61081ef2566glennrp
377ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR04PixelRed(pixel) \
3788e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3794c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelRed(image,(pixel))) \
3808e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
3814c08aed51c5899665ade97263692328eea4af106cristy     SetPixelRed(image,\
3824c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3838e58efdecda887b08ef730d68290a61081ef2566glennrp   }
38454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelGreen(pixel) \
3858e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3864c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar(GetPixelGreen(image,(pixel)))\
3878e58efdecda887b08ef730d68290a61081ef2566glennrp       & 0xf0; \
3884c08aed51c5899665ade97263692328eea4af106cristy     SetPixelGreen(image,\
3894c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3908e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelBlue(pixel) \
3928e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
3938e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
3944c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))) & 0xf0; \
3954c08aed51c5899665ade97263692328eea4af106cristy     SetPixelBlue(image,\
3964c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
3978e58efdecda887b08ef730d68290a61081ef2566glennrp   }
39854cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelAlpha(pixel) \
3998e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4008e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
4014c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))) & 0xf0; \
4024c08aed51c5899665ade97263692328eea4af106cristy     SetPixelAlpha(image,\
4034c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits | (lbr_bits >> 4))), (pixel)); \
4048e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4058e58efdecda887b08ef730d68290a61081ef2566glennrp
40654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGB(pixel) \
407bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
408ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR04PixelRed((pixel)); \
40954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelGreen((pixel)); \
41054cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelBlue((pixel)); \
411bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4128e58efdecda887b08ef730d68290a61081ef2566glennrp
41354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR04PixelRGBA(pixel) \
414bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
41554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelRGB((pixel)); \
41654cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR04PixelAlpha((pixel)); \
417bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4188e58efdecda887b08ef730d68290a61081ef2566glennrp
4198e58efdecda887b08ef730d68290a61081ef2566glennrp
4208e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR08: Replicate top 8 bits */
4218e58efdecda887b08ef730d68290a61081ef2566glennrp
42205001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR08PacketRed(pixelpacket) \
4238e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4248e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).red); \
4258e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleCharToQuantum((lbr_bits)); \
4268e58efdecda887b08ef730d68290a61081ef2566glennrp   }
42791d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketGreen(pixelpacket) \
4288e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4298e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).green); \
4308e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleCharToQuantum((lbr_bits)); \
4318e58efdecda887b08ef730d68290a61081ef2566glennrp   }
43291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketBlue(pixelpacket) \
4338e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4348e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).blue); \
4358e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleCharToQuantum((lbr_bits)); \
4368e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4374c08aed51c5899665ade97263692328eea4af106cristy#define LBR08PacketAlpha(pixelpacket) \
4388e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4394c08aed51c5899665ade97263692328eea4af106cristy     unsigned char lbr_bits=ScaleQuantumToChar((pixelpacket).alpha); \
4404c08aed51c5899665ade97263692328eea4af106cristy     (pixelpacket).alpha=ScaleCharToQuantum((lbr_bits)); \
4418e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4428e58efdecda887b08ef730d68290a61081ef2566glennrp
44391d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGB(pixelpacket) \
444bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
44505001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR08PacketRed((pixelpacket)); \
44691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketGreen((pixelpacket)); \
44791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketBlue((pixelpacket)); \
448bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4498e58efdecda887b08ef730d68290a61081ef2566glennrp
45091d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR08PacketRGBO(pixelpacket) \
451bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
45291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR08PacketRGB((pixelpacket)); \
4534c08aed51c5899665ade97263692328eea4af106cristy        LBR08PacketAlpha((pixelpacket)); \
454bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4558e58efdecda887b08ef730d68290a61081ef2566glennrp
456ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR08PixelRed(pixel) \
4578e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4588e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
4594c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelRed(image,(pixel))); \
4604c08aed51c5899665ade97263692328eea4af106cristy     SetPixelRed(image,\
4614c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4628e58efdecda887b08ef730d68290a61081ef2566glennrp   }
46354cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelGreen(pixel) \
4648e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4658e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
4664c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelGreen(image,(pixel))); \
4674c08aed51c5899665ade97263692328eea4af106cristy     SetPixelGreen(image,\
4684c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4698e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47054cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelBlue(pixel) \
4718e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4728e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
4734c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelBlue(image,(pixel))); \
4744c08aed51c5899665ade97263692328eea4af106cristy     SetPixelBlue(image,\
4754c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4768e58efdecda887b08ef730d68290a61081ef2566glennrp   }
47754cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelAlpha(pixel) \
4788e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
4798e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned char lbr_bits= \
4804c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToChar(GetPixelAlpha(image,(pixel))); \
4814c08aed51c5899665ade97263692328eea4af106cristy     SetPixelAlpha(image,\
4824c08aed51c5899665ade97263692328eea4af106cristy       ScaleCharToQuantum((lbr_bits)), (pixel)); \
4838e58efdecda887b08ef730d68290a61081ef2566glennrp   }
4848e58efdecda887b08ef730d68290a61081ef2566glennrp
48554cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelRGB(pixel) \
486bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
487ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR08PixelRed((pixel)); \
48854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelGreen((pixel)); \
48954cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelBlue((pixel)); \
490bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4918e58efdecda887b08ef730d68290a61081ef2566glennrp
49254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR08PixelRGBA(pixel) \
493bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
49454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelRGB((pixel)); \
49554cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR08PixelAlpha((pixel)); \
496bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
4978e58efdecda887b08ef730d68290a61081ef2566glennrp
4988e58efdecda887b08ef730d68290a61081ef2566glennrp
4998e58efdecda887b08ef730d68290a61081ef2566glennrp/* LBR16: Replicate top 16 bits */
5008e58efdecda887b08ef730d68290a61081ef2566glennrp
50105001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp#define LBR16PacketRed(pixelpacket) \
5028e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5038e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).red); \
5048e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).red=ScaleShortToQuantum((lbr_bits)); \
5058e58efdecda887b08ef730d68290a61081ef2566glennrp   }
50691d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketGreen(pixelpacket) \
5078e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5088e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).green); \
5098e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).green=ScaleShortToQuantum((lbr_bits)); \
5108e58efdecda887b08ef730d68290a61081ef2566glennrp   }
51191d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketBlue(pixelpacket) \
5128e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5138e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).blue); \
5148e58efdecda887b08ef730d68290a61081ef2566glennrp     (pixelpacket).blue=ScaleShortToQuantum((lbr_bits)); \
5158e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5164c08aed51c5899665ade97263692328eea4af106cristy#define LBR16PacketAlpha(pixelpacket) \
5178e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5184c08aed51c5899665ade97263692328eea4af106cristy     unsigned short lbr_bits=ScaleQuantumToShort((pixelpacket).alpha); \
5194c08aed51c5899665ade97263692328eea4af106cristy     (pixelpacket).alpha=ScaleShortToQuantum((lbr_bits)); \
5208e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5218e58efdecda887b08ef730d68290a61081ef2566glennrp
52291d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGB(pixelpacket) \
523bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
52405001c3561dc5a341d5e0bfb88a6570bbdf359a1glennrp        LBR16PacketRed((pixelpacket)); \
52591d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketGreen((pixelpacket)); \
52691d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketBlue((pixelpacket)); \
527bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5288e58efdecda887b08ef730d68290a61081ef2566glennrp
52991d99255dd77083750426ba5463e002a586bc9a6glennrp#define LBR16PacketRGBO(pixelpacket) \
530bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
53191d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR16PacketRGB((pixelpacket)); \
5324c08aed51c5899665ade97263692328eea4af106cristy        LBR16PacketAlpha((pixelpacket)); \
533bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5348e58efdecda887b08ef730d68290a61081ef2566glennrp
535ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy#define LBR16PixelRed(pixel) \
5368e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5378e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
5384c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToShort(GetPixelRed(image,(pixel))); \
5394c08aed51c5899665ade97263692328eea4af106cristy     SetPixelRed(image,\
5404c08aed51c5899665ade97263692328eea4af106cristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5418e58efdecda887b08ef730d68290a61081ef2566glennrp   }
54254cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelGreen(pixel) \
5438e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5448e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
5454c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToShort(GetPixelGreen(image,(pixel))); \
5464c08aed51c5899665ade97263692328eea4af106cristy     SetPixelGreen(image,\
5474c08aed51c5899665ade97263692328eea4af106cristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5488e58efdecda887b08ef730d68290a61081ef2566glennrp   }
54954cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelBlue(pixel) \
5508e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5518e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
5524c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToShort(GetPixelBlue(image,(pixel))); \
5534c08aed51c5899665ade97263692328eea4af106cristy     SetPixelBlue(image,\
5544c08aed51c5899665ade97263692328eea4af106cristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5558e58efdecda887b08ef730d68290a61081ef2566glennrp   }
55654cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelAlpha(pixel) \
5578e58efdecda887b08ef730d68290a61081ef2566glennrp   { \
5588e58efdecda887b08ef730d68290a61081ef2566glennrp     unsigned short lbr_bits= \
5594c08aed51c5899665ade97263692328eea4af106cristy       ScaleQuantumToShort(GetPixelAlpha(image,(pixel))); \
5604c08aed51c5899665ade97263692328eea4af106cristy     SetPixelAlpha(image,\
5614c08aed51c5899665ade97263692328eea4af106cristy       ScaleShortToQuantum((lbr_bits)),(pixel)); \
5628e58efdecda887b08ef730d68290a61081ef2566glennrp   }
5638e58efdecda887b08ef730d68290a61081ef2566glennrp
56454cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelRGB(pixel) \
565bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
566ef61831f94757bbb7fd66e3f5d1aca8a19c0b58ecristy        LBR16PixelRed((pixel)); \
56754cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelGreen((pixel)); \
56854cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelBlue((pixel)); \
569bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5708e58efdecda887b08ef730d68290a61081ef2566glennrp
57154cf79782d2eba6612b706093f62474beb855c8dglennrp#define LBR16PixelRGBA(pixel) \
572bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        { \
57354cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelRGB((pixel)); \
57454cf79782d2eba6612b706093f62474beb855c8dglennrp        LBR16PixelAlpha((pixel)); \
575bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp        }
5768e58efdecda887b08ef730d68290a61081ef2566glennrp
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Establish thread safety.
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is claimed to be safe on these platforms:
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setjmp/longjmp is alleged to be unsafe on these platforms:
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef SETJMP_IS_THREAD_SAFE
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_SETJMP_NOT_THREAD_SAFE
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
588cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  *ping_semaphore = (SemaphoreInfo *) NULL;
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This temporary until I set up malloc'ed object attributes array.
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Recompile with MNG_MAX_OBJECTS=65536L to avoid this limit but
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  waste more memory.
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MNG_MAX_OBJECTS 256
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  If this not defined, spec is interpreted strictly.  If it is
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  defined, an attempt will be made to recover from some errors,
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  including
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      o global PLTE too short
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef MNG_LOOSE
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Don't try to define PNG_MNG_FEATURES_SUPPORTED here.  Make sure
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  it's defined in libpng/pngconf.h, version 1.0.9 or later.  It won't work
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  with earlier versions of libpng.  From libpng-1.0.3a to libpng-1.0.8,
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_READ|WRITE_EMPTY_PLTE were used but those have been deprecated in
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  libpng in favor of PNG_MNG_FEATURES_SUPPORTED, so we set them here.
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNG_MNG_FEATURES_SUPPORTED is disabled by default in libpng-1.0.9 and
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  will be enabled by default in libpng-1.2.0.
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_MNG_FEATURES_SUPPORTED
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_READ_EMPTY_PLTE_SUPPORTED
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  ifndef PNG_WRITE_EMPTY_PLTE_SUPPORTED
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#    define PNG_WRITE_EMPTY_PLTE_SUPPORTED
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#  endif
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
625bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  Maximum valid size_t in PNG/MNG chunks is (2^31)-1
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This macro is only defined in libpng-1.0.3 and later.
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Previously it was PNG_MAX_UINT but that was deprecated in libpng-1.2.6
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_UINT_31_MAX
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_UINT_31_MAX (png_uint_32) 0x7fffffffL
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Constant strings for known chunk types.  If you need to add a chunk,
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  add a string holding the name here.   To make the code more
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  portable, we use ASCII numbers like this, not characters.
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MHDR[5]={ 77,  72,  68,  82, (png_byte) '\0'};
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BACK[5]={ 66,  65,  67,  75, (png_byte) '\0'};
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_BASI[5]={ 66,  65,  83,  73, (png_byte) '\0'};
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLIP[5]={ 67,  76,  73,  80, (png_byte) '\0'};
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_CLON[5]={ 67,  76,  79,  78, (png_byte) '\0'};
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DEFI[5]={ 68,  69,  70,  73, (png_byte) '\0'};
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DHDR[5]={ 68,  72,  68,  82, (png_byte) '\0'};
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_DISC[5]={ 68,  73,  83,  67, (png_byte) '\0'};
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_ENDL[5]={ 69,  78,  68,  76, (png_byte) '\0'};
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_FRAM[5]={ 70,  82,  65,  77, (png_byte) '\0'};
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IEND[5]={ 73,  69,  78,  68, (png_byte) '\0'};
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IHDR[5]={ 73,  72,  68,  82, (png_byte) '\0'};
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JHDR[5]={ 74,  72,  68,  82, (png_byte) '\0'};
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_LOOP[5]={ 76,  79,  79,  80, (png_byte) '\0'};
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MAGN[5]={ 77,  65,  71,  78, (png_byte) '\0'};
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MEND[5]={ 77,  69,  78,  68, (png_byte) '\0'};
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_MOVE[5]={ 77,  79,  86,  69, (png_byte) '\0'};
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PAST[5]={ 80,  65,  83,  84, (png_byte) '\0'};
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_PLTE[5]={ 80,  76,  84,  69, (png_byte) '\0'};
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SAVE[5]={ 83,  65,  86,  69, (png_byte) '\0'};
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SEEK[5]={ 83,  69,  69,  75, (png_byte) '\0'};
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_SHOW[5]={ 83,  72,  79,  87, (png_byte) '\0'};
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_TERM[5]={ 84,  69,  82,  77, (png_byte) '\0'};
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_bKGD[5]={ 98,  75,  71,  68, (png_byte) '\0'};
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_cHRM[5]={ 99,  72,  82,  77, (png_byte) '\0'};
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAT[5]={ 74,  68,  65,  84, (png_byte) '\0'};
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JDAA[5]={ 74,  68,  65,  65, (png_byte) '\0'};
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JdAA[5]={ 74, 100,  65,  65, (png_byte) '\0'};
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_JSEP[5]={ 74,  83,  69,  80, (png_byte) '\0'};
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_oFFs[5]={111,  70,  70, 115, (png_byte) '\0'};
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristyOther known chunks that are not yet supported by ImageMagick:
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_hIST[5]={104,  73,  83,  84, (png_byte) '\0'};
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_iTXt[5]={105,  84,  88, 116, (png_byte) '\0'};
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sPLT[5]={115,  80,  76,  84, (png_byte) '\0'};
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_sTER[5]={115,  84,  69,  82, (png_byte) '\0'};
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tEXt[5]={116,  69,  88, 116, (png_byte) '\0'};
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_tIME[5]={116,  73,  77,  69, (png_byte) '\0'};
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic png_byte FARDATA mng_zTXt[5]={122,  84,  88, 116, (png_byte) '\0'};
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBox
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6978182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  long
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    left,
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    right,
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    top,
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bottom;
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBox;
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngPair
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  volatile long
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    a,
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    b;
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngPair;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngBuffer
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height,
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width;
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte[256];
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reference_count;
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    alpha_sample_depth,
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    compression_method,
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_type,
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    concrete,
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    filter_method,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen,
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_type,
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    interlace_method,
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pixel_sample_depth,
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    plte_length,
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sample_depth,
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngBuffer;
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _MngInfo
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBuffer
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ob[MNG_MAX_OBJECTS];
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image *
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image;
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RectangleInfo
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page;
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    adjoin,
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bytes_in_read_buffer,
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    found_empty_plte,
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_backgrounds,
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_chrms,
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_gammas,
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_palettes,
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_physs,
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    equal_srgbs,
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    framing_mode,
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_bkgd,
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_chrm,
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_gama,
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_phys,
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_sbit,
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_global_srgb,
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_saved_bkgd_index,
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_chrm,
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_gama,
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_plte,
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    have_write_global_srgb,
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_fram,
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    old_framing_mode,
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    saved_bkgd_index;
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    new_number_colors;
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
793bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_found,
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_count[256],
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_iteration[256],
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scenes_found,
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_off[MNG_MAX_OBJECTS],
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_off[MNG_MAX_OBJECTS];
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clip,
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame,
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_box,
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_clip[MNG_MAX_OBJECTS];
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /* These flags could be combined into one byte */
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    exists[MNG_MAX_OBJECTS],
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frozen[MNG_MAX_OBJECTS],
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_active[256],
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    invisible[MNG_MAX_OBJECTS],
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    viewable[MNG_MAX_OBJECTS];
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_jump[256];
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_colorp
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte;
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_color_8
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_sbit;
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_buffer[8],
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns[256];
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  float
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_gamma;
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ChromaticityInfo
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_chrm;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RenderingIntent
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_srgb_intent;
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
83935ef824baa82511126ff0072ae30eee0da9c05a3cristy  unsigned int
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    delay,
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_plte_length,
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_trns_length,
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_x_pixels_per_unit,
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_y_pixels_per_unit,
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_width,
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_height,
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ticks_per_second;
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
849b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  MagickBooleanType
850b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    need_blob;
851b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IsPalette,
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    global_phys_unit_type,
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_warning,
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    clon_warning,
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    dhdr_warning,
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jhdr_warning,
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_warning,
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    past_warning,
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phyg_warning,
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    phys_warning,
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sbit_warning,
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    show_warning,
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type,
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng,
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_colortype,
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png_depth,
8691868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_level,
8701868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_strategy,
8711868258559ddf946fa73ef72dd43507b32623705glennrp    write_png_compression_filter,
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png8,
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png24,
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_png32;
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
877bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_width,
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_height;
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_depth,
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_color_type,
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_compression_method,
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_filter_type,
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_interlace_method,
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_red,
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_green,
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_blue,
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_alpha,
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    basi_viewable;
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_16
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_first,
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_last,
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mb,
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_ml,
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mr,
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mt,
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_mx,
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_my,
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methx,
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magn_methy;
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_global_bkgd;
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* Added at version 6.6.6-7 */
91026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  MagickBooleanType
91126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
91226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
913a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
91426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_EXIF,
91526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
91626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
91726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
91826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
91926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
92026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
92126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
922a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    ping_exclude_tRNS,
92326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
92426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
9258d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_exclude_zTXt,
9268d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap;
92726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} MngInfo;
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* VER */
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
9351e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WritePNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
9381e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WriteMNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
9421e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WriteJNGImage(const ImageInfo *,Image *,ExceptionInfo *);
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9450c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if PNG_LIBPNG_VER > 10011
9460c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
947fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
9480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#if (MAGICKCORE_QUANTUM_DEPTH >= 16)
9490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrpstatic MagickBooleanType
950fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrpLosslessReduceDepthOK(Image *image)
9510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp{
9529d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp    /* Reduce bit depth if it can be reduced losslessly from 16+ to 8.
95367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
95467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * This is true if the high byte and the next highest byte of
95567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * each sample of the image, the colormap, and the background color
9563faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are equal to each other.  We check this by seeing if the samples
9573faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * are unchanged when we scale them down to 8 and back up to Quantum.
95867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     *
95967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp     * We don't use the method GetImageDepth() because it doesn't check
9603faa9a3fb01696daaf976d595f492cb530bffb21glennrp     * background and doesn't handle PseudoClass specially.
9619d0ea4d0d750fa124d7b83da98ed582d59c1aab0glennrp     */
96205a549971fd661147ade177e2bc10f6cfcfc32b4glennrp
9633faa9a3fb01696daaf976d595f492cb530bffb21glennrp#define QuantumToCharToQuantumEqQuantum(quantum) \
9643faa9a3fb01696daaf976d595f492cb530bffb21glennrp  ((ScaleCharToQuantum((unsigned char) ScaleQuantumToChar(quantum))) == quantum)
9653faa9a3fb01696daaf976d595f492cb530bffb21glennrp
96667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    MagickBooleanType
96767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      ok_to_reduce=MagickFalse;
96867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
96903e11f6e8d7f01a32b53d7e8e6a3bfd5ef1c5c9dglennrp    if (image->depth >= 16)
9700c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      {
9710c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9724c08aed51c5899665ade97263692328eea4af106cristy        const Quantum
9730c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          *p;
9740c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9750c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        ok_to_reduce=
9763faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.red) &&
9773faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.green) &&
9783faa9a3fb01696daaf976d595f492cb530bffb21glennrp           QuantumToCharToQuantumEqQuantum(image->background_color.blue) ?
9793faa9a3fb01696daaf976d595f492cb530bffb21glennrp           MagickTrue : MagickFalse;
9800c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9810c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse && image->storage_class == PseudoClass)
9820c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
9830c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            int indx;
9840c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
9850c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (indx=0; indx < (ssize_t) image->colors; indx++)
9860c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
9873faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=(
9883faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9893faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].red) &&
9903faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9913faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].green) &&
9923faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   QuantumToCharToQuantumEqQuantum(
9933faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   image->colormap[indx].blue)) ?
9943faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
9953faa9a3fb01696daaf976d595f492cb530bffb21glennrp
9960c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
9973faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   break;
9980c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
9990c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10000c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10010c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if ((ok_to_reduce != MagickFalse) &&
10020c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (image->storage_class != PseudoClass))
10030c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10040c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            ssize_t
10050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              y;
10060c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10070c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            register ssize_t
10080c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              x;
10090c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10100c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            for (y=0; y < (ssize_t) image->rows; y++)
10110c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            {
10120c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
10130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10144c08aed51c5899665ade97263692328eea4af106cristy              if (p == (const Quantum *) NULL)
10150c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                {
10160c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  ok_to_reduce = MagickFalse;
10170c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10180c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                }
10190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10200c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
10210c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              {
10223faa9a3fb01696daaf976d595f492cb530bffb21glennrp                ok_to_reduce=
10234c08aed51c5899665ade97263692328eea4af106cristy                   QuantumToCharToQuantumEqQuantum(GetPixelRed(image,p)) &&
10244c08aed51c5899665ade97263692328eea4af106cristy                   QuantumToCharToQuantumEqQuantum(GetPixelGreen(image,p)) &&
10254c08aed51c5899665ade97263692328eea4af106cristy                   QuantumToCharToQuantumEqQuantum(GetPixelBlue(image,p)) ?
10263faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   MagickTrue : MagickFalse;
10270c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10280c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                if (ok_to_reduce == MagickFalse)
10290c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                  break;
10300c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1031ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                p+=GetPixelChannels(image);
10320c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp              }
10338640fb5e9b1094f35f8beab436f81661b8a99448glennrp              if (x >= 0)
10340c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp                break;
10350c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            }
10360c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
10370c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10380c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp        if (ok_to_reduce != MagickFalse)
10390c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          {
10400c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1041fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    OK to reduce PNG bit depth to 8 without loss of info");
10420c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp          }
1043a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        else
1044a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          {
1045a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1046fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                "    Not OK to reduce PNG bit depth to 8 without loss of info");
1047a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          }
10480c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp      }
10490c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
10500c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp    return ok_to_reduce;
10510c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp}
10520c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH >= 16 */
10530c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1054e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic int
1055cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
10560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1057e610a071534e448c46460a5aa39ede33bf56b329glennrp  switch (intent)
1058e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1059e610a071534e448c46460a5aa39ede33bf56b329glennrp    case PerceptualIntent:
1060e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 0;
10610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1062e610a071534e448c46460a5aa39ede33bf56b329glennrp    case RelativeIntent:
1063e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 1;
10640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1065e610a071534e448c46460a5aa39ede33bf56b329glennrp    case SaturationIntent:
1066e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 2;
10670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1068e610a071534e448c46460a5aa39ede33bf56b329glennrp    case AbsoluteIntent:
1069e610a071534e448c46460a5aa39ede33bf56b329glennrp       return 3;
10700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1071e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1072e610a071534e448c46460a5aa39ede33bf56b329glennrp       return -1;
1073e610a071534e448c46460a5aa39ede33bf56b329glennrp  }
1074e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1075e610a071534e448c46460a5aa39ede33bf56b329glennrp
1076e610a071534e448c46460a5aa39ede33bf56b329glennrpstatic RenderingIntent
1077cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_RenderingIntent_from_PNG_RenderingIntent(const int ping_intent)
10780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp{
1079cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  switch (ping_intent)
1080e610a071534e448c46460a5aa39ede33bf56b329glennrp  {
1081e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 0:
1082e610a071534e448c46460a5aa39ede33bf56b329glennrp      return PerceptualIntent;
10830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1084e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 1:
1085e610a071534e448c46460a5aa39ede33bf56b329glennrp      return RelativeIntent;
10860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1087e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 2:
1088e610a071534e448c46460a5aa39ede33bf56b329glennrp      return SaturationIntent;
10890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1090e610a071534e448c46460a5aa39ede33bf56b329glennrp    case 3:
1091e610a071534e448c46460a5aa39ede33bf56b329glennrp      return AbsoluteIntent;
10920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1093e610a071534e448c46460a5aa39ede33bf56b329glennrp    default:
1094e610a071534e448c46460a5aa39ede33bf56b329glennrp      return UndefinedIntent;
1095e610a071534e448c46460a5aa39ede33bf56b329glennrp    }
1096e610a071534e448c46460a5aa39ede33bf56b329glennrp}
1097e610a071534e448c46460a5aa39ede33bf56b329glennrp
1098bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x > y)
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11050c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1106bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic inline ssize_t MagickMin(const ssize_t x,const ssize_t y)
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (x < y)
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(x);
11100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(y);
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11130c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp
1114dbb105fc25903e800273f7e980c0553060858a68glennrp
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1120dbb105fc25903e800273f7e980c0553060858a68glennrp%   I m a g e I s G r a y                                                     %
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1125dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
11264c08aed51c5899665ade97263692328eea4af106cristy%   Like IsImageGray except does not change DirectClass to PseudoClass        %
1127dbb105fc25903e800273f7e980c0553060858a68glennrp%                                                                             %
1128dbb105fc25903e800273f7e980c0553060858a68glennrp%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1130dbb105fc25903e800273f7e980c0553060858a68glennrpstatic MagickBooleanType ImageIsGray(Image *image)
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11324c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1135bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
1137dbb105fc25903e800273f7e980c0553060858a68glennrp    x,
1138dbb105fc25903e800273f7e980c0553060858a68glennrp    y;
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
1143dbb105fc25903e800273f7e980c0553060858a68glennrp    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1144dbb105fc25903e800273f7e980c0553060858a68glennrp
1145dbb105fc25903e800273f7e980c0553060858a68glennrp  if (image->storage_class == PseudoClass)
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1147dbb105fc25903e800273f7e980c0553060858a68glennrp      for (i=0; i < (ssize_t) image->colors; i++)
11484c08aed51c5899665ade97263692328eea4af106cristy        if (IsPixelPacketGray(image->colormap+i) == MagickFalse)
1149dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
1150dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickTrue);
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1152bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
11554c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
1156dbb105fc25903e800273f7e980c0553060858a68glennrp      return(MagickFalse);
1157dbb105fc25903e800273f7e980c0553060858a68glennrp    for (x=(ssize_t) image->columns-1; x >= 0; x--)
1158dbb105fc25903e800273f7e980c0553060858a68glennrp    {
11594c08aed51c5899665ade97263692328eea4af106cristy       if (IsPixelGray(image,p) == MagickFalse)
1160dbb105fc25903e800273f7e980c0553060858a68glennrp          return(MagickFalse);
1161ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy       p+=GetPixelChannels(image);
1162dbb105fc25903e800273f7e980c0553060858a68glennrp    }
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1164dbb105fc25903e800273f7e980c0553060858a68glennrp  return(MagickTrue);
1165dbb105fc25903e800273f7e980c0553060858a68glennrp}
1166d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MAGICKCORE_PNG_DELEGATE */
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s M N G                                                                 %
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsMNG() returns MagickTrue if the image format type, identified by the
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is MNG.
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsMNG method is:
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsMNG(const unsigned char *magick,const size_t length)
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\212MNG\r\n\032\n",8) == 0)
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s J N G                                                                 %
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsJNG() returns MagickTrue if the image format type, identified by the
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is JNG.
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsJNG method is:
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsJNG(const unsigned char *magick,const size_t length)
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\213JNG\r\n\032\n",8) == 0)
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P N G                                                                 %
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPNG() returns MagickTrue if the image format type, identified by the
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PNG.
12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsPNG method is:
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPNG(const unsigned char *magick,const size_t length)
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 8)
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
12720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"\211PNG\r\n\032\n",8) == 0)
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
12750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1284d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER > 10011)
1285bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic size_t WriteBlobMSBULong(Image *image,const size_t value)
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    buffer[4];
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=(unsigned char) (value >> 24);
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[1]=(unsigned char) (value >> 16);
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[2]=(unsigned char) (value >> 8);
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[3]=(unsigned char) value;
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((size_t) WriteBlob(image,4,buffer));
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGLong(png_bytep p,png_uint_32 value)
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1307a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#if defined(JNG_SUPPORTED)
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGsLong(png_bytep p,png_int_32 value)
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 24) & 0xff);
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 16) & 0xff);
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1315a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp#endif
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGShort(png_bytep p,png_uint_16 value)
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) ((value >> 8) & 0xff);
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *p++=(png_byte) (value & 0xff);
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void PNGType(png_bytep p,png_bytep type)
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(p,type,4*sizeof(png_byte));
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132803812ae402fb53d548f0e1d7d14720768f803c2dglennrpstatic void LogPNGChunk(MagickBooleanType logging, png_bytep type,
132903812ae402fb53d548f0e1d7d14720768f803c2dglennrp   size_t length)
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1333e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Writing %c%c%c%c chunk, length: %.20g",
1334e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      type[0],type[1],type[2],type[3],(double) length);
13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1336d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1342d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if PNG_LIBPNG_VER > 10011
13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P N G I m a g e                                                   %
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPNGImage() reads a Portable Network Graphics (PNG) or
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file and returns it.  It
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image or set of images.
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPNGImage method is:
13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do, more or less in chronological order (as of version 5.5.2,
13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   November 26, 2002 -- glennrp -- see also "To do" under WriteMNGImage):
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Get 16-bit cheap transparency working.
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG decoding is supposed to be in full MNG-LC compliance)
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them into output PNG files according to the PNG
13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    (At this point, PNG encoding should be in full MNG compliance)
13833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide options for choice of background to use when the MNG BACK
13853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    chunk is not present or is not mandatory (i.e., leave transparent,
13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    user specified, MNG BACK, PNG bKGD)
13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Implement LOOP/ENDL [done, but could do discretionary loops more
13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    efficiently by linking in the duplicate frames.].
13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Decode and act on the MHDR simplicity profile (offer option to reject
13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files or attempt to process them anyway when the profile isn't LC or VLC).
13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG without Delta-PNG.
13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BACK [done a while ago except for background image ID]
13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MOVE [done 15 May 1999]
13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  CLIP [done 15 May 1999]
13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  DISC [done 19 May 1999]
14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SAVE [partially done 19 May 1999 (marks objects frozen)]
14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SEEK [partially done 19 May 1999 (discard function only)]
14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  SHOW
14033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  PAST
14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  BASI
14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  MNG-level tEXt/iTXt/zTXt
14063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYg
14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  pHYs
14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  sBIT
14093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  bKGD
14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        o  iTXt (wait for libpng implementation).
14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use the scene signature to discover when an identical scene is
14133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    being reused, and just point to the original image->exception instead
14143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    of storing another set of pixels.  This not specific to MNG
14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    but could be applied generally.
14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Upgrade to full MNG with Delta-PNG.
14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    JNG tEXt/iTXt/zTXt
14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    We will not attempt to read files containing the CgBI chunk.
14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    They are really Xcode files meant for display on the iPhone.
14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    These are not valid PNG files and it is impossible to recover
1424f54e295d6fa414fa04aa4f43767c20eda8ae555eglennrp%    the original PNG from files that have been converted to Xcode-PNG,
14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    since irretrievable loss of color data has occurred due to the
14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    use of premultiplied alpha.
14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  This the function that does the actual reading of data.  It is
14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  the same as the one supplied in libpng, except that it receives the
14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  datastream from the ReadBlob() function instead of standard input.
14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,data);
14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
14523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          char
14533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            msg[MaxTextExtent];
14543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14553b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy          (void) FormatLocaleString(msg,MaxTextExtent,
1456e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "Expected %.20g bytes; found %.20g bytes",(double) length,
1457e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            (double) check);
14583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_warning(png_ptr,msg);
14593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_error(png_ptr,"Read Exception");
14603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(PNG_READ_EMPTY_PLTE_SUPPORTED) && \
14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    !defined(PNG_MNG_FEATURES_SUPPORTED)
14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* We use mng_get_data() instead of png_get_data() if we have a libpng
14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * older than libpng-1.0.3a, which was the first to allow the empty
14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * PLTE, or a newer libpng in which PNG_MNG_FEATURES_SUPPORTED was
14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * ifdef'ed out.  Earlier versions would crash if the bKGD chunk was
14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * encountered after an empty PLTE, so we have to look ahead for bKGD
14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * chunks and remove them from the datastream that is passed to libpng,
14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy * and store their contents for later use.
14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */
14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void mng_get_data(png_structp png_ptr,png_bytep data,png_size_t length)
14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_size_t
14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    check;
14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1485bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
14863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) png_get_io_ptr(png_ptr);
14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) mng_info->image;
14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (mng_info->bytes_in_read_buffer && length)
14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    data[i]=mng_info->read_buffer[i];
14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->bytes_in_read_buffer--;
14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length--;
14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i++;
14973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
14983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
14993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      check=(png_size_t) ReadBlob(image,(size_t) length,(char *) data);
15010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"Read Exception");
15040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (length == 4)
15063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
15073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 0))
15093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_PLTE,4) == 0)
15153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->found_empty_plte=MagickTrue;
15163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_IEND,4) == 0)
15173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
15183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->found_empty_plte=MagickFalse;
15193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->have_saved_bkgd_index=MagickFalse;
15203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
15213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((data[0] == 0) && (data[1] == 0) && (data[2] == 0) &&
15243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (data[3] == 1))
15253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
15263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              check=(png_size_t) ReadBlob(image,(size_t) length,
15273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (char *) mng_info->read_buffer);
15283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->read_buffer[4]=0;
15293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->bytes_in_read_buffer=4;
15303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (memcmp(mng_info->read_buffer,mng_bKGD,4) == 0)
15313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->found_empty_plte)
15323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
15333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
15343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Skip the bKGD data byte and CRC.
15353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
15363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t)
15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      ReadBlob(image,5,(char *) mng_info->read_buffer);
15383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    check=(png_size_t) ReadBlob(image,(size_t) length,
15393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (char *) mng_info->read_buffer);
15403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->saved_bkgd_index=mng_info->read_buffer[0];
15413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->have_saved_bkgd_index=MagickTrue;
15423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->bytes_in_read_buffer=0;
15433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
15443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
15453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
15463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15503ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_put_data(png_structp png_ptr,png_bytep data,png_size_t length)
15513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
15533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
15543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_io_ptr(png_ptr);
15563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length)
15573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
15583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_size_t
15593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        check;
15603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      check=(png_size_t) WriteBlob(image,(size_t) length,data);
15620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (check != length)
15643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_error(png_ptr,"WriteBlob Failed");
15653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
15663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void png_flush_data(png_structp png_ptr)
15693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
15703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) png_ptr;
15713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
15743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int PalettesAreEqual(Image *a,Image *b)
15753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
15773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
15783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
15793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((a == (Image *) NULL) || (b == (Image *) NULL))
15803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
15810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->storage_class != PseudoClass || b->storage_class != PseudoClass)
15833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
15840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (a->colors != b->colors)
15863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((int) MagickFalse);
15870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) a->colors; i++)
15893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
15903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((a->colormap[i].red != b->colormap[i].red) ||
15913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].green != b->colormap[i].green) ||
15923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (a->colormap[i].blue != b->colormap[i].blue))
15933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((int) MagickFalse);
15943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
15950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
15963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((int) MagickTrue);
15973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
15983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
15993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void MngInfoDiscardObject(MngInfo *mng_info,int i)
16013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (i && (i < MNG_MAX_OBJECTS) && (mng_info != (MngInfo *) NULL) &&
16033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i] && !mng_info->frozen[i])
16043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
16063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[i] != (MngBuffer *) NULL)
16073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
16083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count > 0)
16093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[i]->reference_count--;
16100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[i]->reference_count == 0)
16123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
16133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->ob[i]->image != (Image *) NULL)
16143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[i]->image=DestroyImage(mng_info->ob[i]->image);
16150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[i]=DestroyString(mng_info->ob[i]);
16173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
16183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
16193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->ob[i]=(MngBuffer *) NULL;
16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
16213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[i]=MagickFalse;
16223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->invisible[i]=MagickFalse;
16233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->viewable[i]=MagickFalse;
16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frozen[i]=MagickFalse;
16253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->x_off[i]=0;
16263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->y_off[i]=0;
16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].left=0;
1628bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
16293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->object_clip[i].top=0;
1630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
163421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrpstatic void MngInfoFreeStruct(MngInfo *mng_info,
163521f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    MagickBooleanType *have_mng_structure)
16363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
163721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp  if (*have_mng_structure != MagickFalse && (mng_info != (MngInfo *) NULL))
16383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
1639bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      register ssize_t
16403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        i;
16413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=1; i < MNG_MAX_OBJECTS; i++)
16433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoDiscardObject(mng_info,i);
16440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->global_plte != (png_colorp) NULL)
16463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->global_plte=(png_colorp)
16473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          RelinquishMagickMemory(mng_info->global_plte);
16480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info=(MngInfo *) RelinquishMagickMemory(mng_info);
16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *have_mng_structure=MagickFalse;
16513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_minimum_box(MngBox box1,MngBox box2)
16553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
16573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box;
16583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  box=box1;
16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.left < box2.left)
16613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.left=box2.left;
16620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.top < box2.top)
16643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.top=box2.top;
16650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.right > box2.right)
16673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.right=box2.right;
16680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (box.bottom > box2.bottom)
16703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    box.bottom=box2.bottom;
16710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return box;
16733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngBox mng_read_box(MngBox previous_box,char delta_type,unsigned char *p)
16763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
16773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   MngBox
16783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box;
16793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
16813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read clipping boundaries from DEFI, CLIP, FRAM, or PAST chunk.
16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
1683bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.left=(ssize_t) ((p[0]  << 24) | (p[1]  << 16) | (p[2]  << 8) | p[3]);
1684bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.right=(ssize_t) ((p[4]  << 24) | (p[5]  << 16) | (p[6]  << 8) | p[7]);
1685bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.top=(ssize_t) ((p[8]  << 24) | (p[9]  << 16) | (p[10] << 8) | p[11]);
1686bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  box.bottom=(ssize_t) ((p[12] << 24) | (p[13] << 16) | (p[14] << 8) | p[15]);
16873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
16883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
16893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.left+=previous_box.left;
16903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.right+=previous_box.right;
16913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.top+=previous_box.top;
16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      box.bottom+=previous_box.bottom;
16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
16940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(box);
16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
16973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MngPair mng_read_pair(MngPair previous_pair,int delta_type,
16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char *p)
17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngPair
17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pair;
17033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
1704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    Read two ssize_ts from CLON, MOVE or PAST chunk
17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
17068182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.a=(long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
17078182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  pair.b=(long) ((p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7]);
17080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (delta_type != 0)
17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.a+=previous_pair.a;
17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      pair.b+=previous_pair.b;
17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
17140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(pair);
17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17188182b0758e3429fb8dcd1700f09643fd4d80a41ccristystatic long mng_get_long(unsigned char *p)
17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17208182b0758e3429fb8dcd1700f09643fd4d80a41ccristy  return((long) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]));
17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1723cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGErrorHandler(png_struct *ping,png_const_charp message)
17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
17290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  libpng-%s error: %s", PNG_LIBPNG_VER_STRING,message);
17330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderError,
17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
17360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1737e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
17388371ecc013ff231ce380d8717e517312e62e1f01glennrp  /* A warning about deprecated use of jmpbuf here is unavoidable if you
17398371ecc013ff231ce380d8717e517312e62e1f01glennrp   * are building with libpng-1.4.x and can be ignored.
17408371ecc013ff231ce380d8717e517312e62e1f01glennrp   */
17413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  longjmp(ping->jmpbuf,1);
1742faa852bad40107edae19405e76a299057668d795glennrp#else
1743faa852bad40107edae19405e76a299057668d795glennrp  png_longjmp(ping,1);
1744faa852bad40107edae19405e76a299057668d795glennrp#endif
17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1747cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic void MagickPNGWarningHandler(png_struct *ping,png_const_charp message)
17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(message, "Missing PLTE before tRNS") == 0)
17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error(ping, message);
17540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_error_ptr(ping);
17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1758cc23b9a188db6b1f240825f6d4c52310f5f69765cristy      "  libpng-%s warning: %s", PNG_LIBPNG_VER_STRING,message);
17590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(&image->exception,GetMagickModule(),CoderWarning,
17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    message,"`%s'",image->filename);
17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
1765cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_voidp Magick_png_malloc(png_structp png_ptr,png_uint_32 size)
17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER < 10011)
17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_voidp
17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ret;
17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ret=((png_voidp) AcquireMagickMemory((size_t) size));
17730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ret == NULL)
17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_error("Insufficient memory.");
17760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ret);
17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_voidp) AcquireMagickMemory((size_t) size));
17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Free a pointer.  It is removed from the list at the same time.
17863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1787cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic png_free_ptr Magick_png_free(png_structp png_ptr,png_voidp ptr)
17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_ptr=png_ptr;
17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ptr=RelinquishMagickMemory(ptr);
17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return((png_free_ptr) NULL);
17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int
1800cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_read_raw_profile(Image *image, const ImageInfo *image_info,
18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp text,int ii)
18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *dp;
18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register png_charp
18103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sp;
18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
18133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length,
18143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    nibbles;
18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18190c3e06bd4809f97aeceaeb7c2334d8b2b850c2e1glennrp  const unsigned char
18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12,
18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 13,14,15};
18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  sp=text[ii].text+1;
18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for newline */
18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != '\n')
18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* look for length */
18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp == '\0' || *sp == ' ' || *sp == '\n')
18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1836f2f2727f17ecbb23d902f70bb98f81faabc92dbdcristy  length=(png_uint_32) StringToLong(sp);
18370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
183897f90e23c85b9c58387880125c29d8c99126f83aglennrp  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
183997f90e23c85b9c58387880125c29d8c99126f83aglennrp       "      length: %lu",(unsigned long) length);
184097f90e23c85b9c58387880125c29d8c99126f83aglennrp
18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (*sp != ' ' && *sp != '\n')
18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     sp++;
18430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* allocate space */
18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length == 0)
18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      CoderWarning,"UnableToCopyProfile","`%s'","invalid profile length");
18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18528723e4bcd840478cecfd29891e792edb499cd0e9cristy  profile=BlobToStringInfo((const void *) NULL,length);
18530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (profile == (StringInfo *) NULL)
18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ThrowMagickException(&image->exception,GetMagickModule(),
18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResourceLimitError,"MemoryAllocationFailed","`%s'",
18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "unable to copy profile");
18593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* copy profile, skipping white space and column 1 "=" signs */
18633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  dp=GetStringInfoDatum(profile);
18643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  nibbles=length*2;
18650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1866bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) nibbles; i++)
18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f')
18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (*sp == '\0')
18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(&image->exception,GetMagickModule(),
18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            CoderWarning,"UnableToCopyProfile","`%s'","ran out of data");
18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      sp++;
18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
18790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i%2 == 0)
18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *dp=(unsigned char) (16*unhex[(int) *sp++]);
18820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (*dp++)+=unhex[(int) *sp++];
18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    We have already read "Raw profile type.
18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) SetImageProfile(image,&text[ii].key[17],profile);
18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  profile=DestroyStringInfo(profile);
18910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
18933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) printf(" Found a generic profile, type %s\n",&text[ii].key[17]);
18940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return MagickTrue;
18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int read_vpag_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* The unknown chunk structure contains the chunk data:
19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte name[5];
19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_byte *data;
19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_size_t size;
19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Note that libpng has already taken care of the CRC handling.
19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->name[0] != 118 || chunk->name[1] != 112 ||
19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk->name[2] != 65 ||chunk-> name[3] != 103)
19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0); /* Did not recognize */
19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* recognized vpAg */
19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->size != 9)
19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(-1); /* Error return */
19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (chunk->data[8] != 0)
19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(0);  /* ImageMagick requires pixel units */
19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=(Image *) png_get_user_chunk_ptr(ping);
19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1928bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.width=(size_t) ((chunk->data[0] << 24) |
19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
19300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1931bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->page.height=(size_t) ((chunk->data[4] << 24) |
19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Return one of the following: */
19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(-n);  chunk had an error */
19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(0);  did not recognize */
19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /* return(n);  success */
19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(1);
19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e P N G I m a g e                                             %
19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOnePNGImage() reads a Portable Network Graphics (PNG) image file
19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOnePNGImage method is:
19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOnePNGImage(MngInfo *mng_info, const ImageInfo *image_info,
19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOnePNGImage(MngInfo *mng_info,
19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Read one PNG image */
19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1979cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tIME chunk into the date:modify property */
1980cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp  /* To do: Read the tEXt/Creation Time chunk into the date:create property */
1981cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
19864eb3931feb349dd87142c78503b779228f3e1a0fglennrp    intent,
1987cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    num_raw_profiles,
19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_text,
19894eb3931feb349dd87142c78503b779228f3e1a0fglennrp    num_text_total,
19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
1991faa852bad40107edae19405e76a299057668d795glennrp    pass,
1992faa852bad40107edae19405e76a299057668d795glennrp    ping_bit_depth,
1993faa852bad40107edae19405e76a299057668d795glennrp    ping_color_type,
1994faa852bad40107edae19405e76a299057668d795glennrp    ping_interlace_method,
1995faa852bad40107edae19405e76a299057668d795glennrp    ping_compression_method,
1996faa852bad40107edae19405e76a299057668d795glennrp    ping_filter_method,
19974eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_num_trans,
19984eb3931feb349dd87142c78503b779228f3e1a0fglennrp    unit_type;
19994eb3931feb349dd87142c78503b779228f3e1a0fglennrp
20004eb3931feb349dd87142c78503b779228f3e1a0fglennrp  double
20014eb3931feb349dd87142c78503b779228f3e1a0fglennrp    file_gamma;
20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2003a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  LongPixelPacket
2004a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    transparent_color;
2005a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
20063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
20074383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging,
20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2010faa852bad40107edae19405e76a299057668d795glennrp  png_bytep
2011faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_alpha;
2012faa852bad40107edae19405e76a299057668d795glennrp
2013faa852bad40107edae19405e76a299057668d795glennrp  png_color_16p
2014faa852bad40107edae19405e76a299057668d795glennrp     ping_background,
2015faa852bad40107edae19405e76a299057668d795glennrp     ping_trans_color;
2016faa852bad40107edae19405e76a299057668d795glennrp
20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
20183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end_info,
20193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
20203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
20223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
20233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_textp
20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    text;
20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2027faa852bad40107edae19405e76a299057668d795glennrp  png_uint_32
2028faa852bad40107edae19405e76a299057668d795glennrp    ping_height,
2029faa852bad40107edae19405e76a299057668d795glennrp    ping_width,
20304eb3931feb349dd87142c78503b779228f3e1a0fglennrp    ping_rowbytes,
20314eb3931feb349dd87142c78503b779228f3e1a0fglennrp    x_resolution,
20324eb3931feb349dd87142c78503b779228f3e1a0fglennrp    y_resolution;
2033faa852bad40107edae19405e76a299057668d795glennrp
20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2038cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2040bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2046bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20504c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
205439992b4dd9b12ef752d55b8e402c069698851f72glennrp    length,
20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    row_offset;
20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2057eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  ssize_t
2058eb3b22a03f31af7f724573d8537cd91fca06ee41cristy    j;
2059eb3b22a03f31af7f724573d8537cd91fca06ee41cristy
20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte unused_chunks[]=
20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    104,  73,  83,  84, (png_byte) '\0',   /* hIST */
20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    105,  84,  88, 116, (png_byte) '\0',   /* iTXt */
20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    112,  67,  65,  76, (png_byte) '\0',   /* pCAL */
20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  67,  65,  76, (png_byte) '\0',   /* sCAL */
20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    115,  80,  76,  84, (png_byte) '\0',   /* sPLT */
20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    116,  73,  77,  69, (png_byte) '\0',   /* tIME */
20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  };
20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
2073fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOnePNGImage()");
20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2076cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
207925c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if (PNG_LIBPNG_VER < 10200)
20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->verbose)
20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    printf("Your PNG library (libpng-%s) is rather old.\n",
20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNG_LIBPNG_VER_STRING);
20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
208561b4c957269727a0a2526edc2331881da8346100glennrp#if (PNG_LIBPNG_VER >= 10400)
208661b4c957269727a0a2526edc2331881da8346100glennrp#  ifndef  PNG_TRANSFORM_GRAY_TO_RGB    /* Added at libpng-1.4.0beta67 */
208761b4c957269727a0a2526edc2331881da8346100glennrp  if (image_info->verbose)
208861b4c957269727a0a2526edc2331881da8346100glennrp    {
208961b4c957269727a0a2526edc2331881da8346100glennrp      printf("Your PNG library (libpng-%s) is an old beta version.\n",
209061b4c957269727a0a2526edc2331881da8346100glennrp           PNG_LIBPNG_VER_STRING);
209161b4c957269727a0a2526edc2331881da8346100glennrp      printf("Please update it.\n");
209261b4c957269727a0a2526edc2331881da8346100glennrp    }
209361b4c957269727a0a2526edc2331881da8346100glennrp#  endif
209461b4c957269727a0a2526edc2331881da8346100glennrp#endif
209561b4c957269727a0a2526edc2331881da8346100glennrp
209661b4c957269727a0a2526edc2331881da8346100glennrp
2097ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info = (QuantumInfo *) NULL;
20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2100a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (logging != MagickFalse)
2101a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    (void)LogMagickEvent(CoderEvent,GetMagickModule(),
2102a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      "  image->matte=%d",(int) image->matte);
2103a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
21040e319739731741c52a6303723e0c8678a0df5579glennrp  /* Set to an out-of-range color unless tRNS chunk is present */
21050e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.red=65537;
21060e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.green=65537;
21070e319739731741c52a6303723e0c8678a0df5579glennrp  transparent_color.blue=65537;
21084c08aed51c5899665ade97263692328eea4af106cristy  transparent_color.alpha=65537;
21090e319739731741c52a6303723e0c8678a0df5579glennrp
2110cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_text = 0;
21114eb3931feb349dd87142c78503b779228f3e1a0fglennrp  num_text_total = 0;
2112cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp  num_raw_profiles = 0;
2113cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
21143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ping=png_create_read_struct_2(PNG_LIBPNG_VER_STRING, image,
2119cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   MagickPNGErrorHandler,MagickPNGWarningHandler, NULL,
2120cf002022280cc4dedb2748ad6f415aac1d44f530glennrp   (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_read_struct(PNG_LIBPNG_VER_STRING,image,
2123cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
21243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
21290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
21313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,(png_info **) NULL,(png_info **) NULL);
21333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  end_info=png_create_info_struct(ping);
21370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end_info == (png_info *) NULL)
21393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,(png_info **) NULL);
21413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
21423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2144cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
21450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2146faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
21473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
21493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
21503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
21513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
21523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2153cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
21543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
21563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
21573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
21580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
21607b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
21617b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
21627b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
21637b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
21640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
21663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
21683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for reading.
21693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2170faa852bad40107edae19405e76a299057668d795glennrp
21713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
21723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_sig_bytes(ping,8);
21730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
21753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
21763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
21773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
21783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
21793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
21813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_permit_empty_plte(ping,MagickTrue);
21823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,image,png_get_data);
21833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
21843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image=image;
21853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->bytes_in_read_buffer=0;
21863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->found_empty_plte=MagickFalse;
21873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->have_saved_bkgd_index=MagickFalse;
21883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_set_read_fn(ping,mng_info,mng_get_data);
21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
21913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
21920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
21933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
21943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_read_fn(ping,image,png_get_data);
21953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
21963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
21973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Ignore unused chunks and all unknown chunks except for vpAg */
21983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, NULL, 0);
21993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 2, mng_vpAg, 1);
22003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_keep_unknown_chunks(ping, 1, unused_chunks,
22013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (int)sizeof(unused_chunks)/5);
22023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Callback for other unknown chunks */
22033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_read_user_chunk_fn(ping, image, read_vpag_chunk_callback);
22043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2206991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#if (PNG_LIBPNG_VER < 10400)
2207991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) && \
2208991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp   (PNG_LIBPNG_VER >= 10200) && (PNG_LIBPNG_VER < 10220) && defined(__i386__)
22093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Disable thread-unsafe features of pnggccrd */
22103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (png_access_version_number() >= 10200)
22113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
22123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 mmx_disable_mask=0;
22133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_uint_32 asm_flags;
22143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW  \
22163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_SUB   \
22173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_AVG   \
22183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
22193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    asm_flags=png_get_asm_flags(ping);
22203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_asm_flags(ping, asm_flags & ~mmx_disable_mask);
22213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2222991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp#  endif
22233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
22243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_info(ping,ping_info);
2226faa852bad40107edae19405e76a299057668d795glennrp
2227faa852bad40107edae19405e76a299057668d795glennrp  png_get_IHDR(ping,ping_info,&ping_width,&ping_height,
2228faa852bad40107edae19405e76a299057668d795glennrp               &ping_bit_depth,&ping_color_type,
2229faa852bad40107edae19405e76a299057668d795glennrp               &ping_interlace_method,&ping_compression_method,
2230faa852bad40107edae19405e76a299057668d795glennrp               &ping_filter_method);
2231faa852bad40107edae19405e76a299057668d795glennrp
2232faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_tRNS(ping, ping_info, &ping_trans_alpha, &ping_num_trans,
2233faa852bad40107edae19405e76a299057668d795glennrp                      &ping_trans_color);
2234faa852bad40107edae19405e76a299057668d795glennrp
2235faa852bad40107edae19405e76a299057668d795glennrp  (void) png_get_bKGD(ping, ping_info, &ping_background);
2236faa852bad40107edae19405e76a299057668d795glennrp
2237faa852bad40107edae19405e76a299057668d795glennrp  if (ping_bit_depth < 8)
22383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2239faa852bad40107edae19405e76a299057668d795glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
2240faa852bad40107edae19405e76a299057668d795glennrp        {
2241faa852bad40107edae19405e76a299057668d795glennrp          png_set_packing(ping);
2242faa852bad40107edae19405e76a299057668d795glennrp          ping_bit_depth = 8;
2243faa852bad40107edae19405e76a299057668d795glennrp        }
22443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2245faa852bad40107edae19405e76a299057668d795glennrp
2246faa852bad40107edae19405e76a299057668d795glennrp  image->depth=ping_bit_depth;
22473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=GetImageQuantumDepth(image,MagickFalse);
2248faa852bad40107edae19405e76a299057668d795glennrp  image->interlace=ping_interlace_method != 0 ? PNGInterlace : NoInterlace;
22493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
22503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2252e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    PNG width: %.20g, height: %.20g",
2253e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) ping_width, (double) ping_height);
22540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG color_type: %d, bit_depth: %d",
2257faa852bad40107edae19405e76a299057668d795glennrp        ping_color_type, ping_bit_depth);
22580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG compression_method: %d",
2261faa852bad40107edae19405e76a299057668d795glennrp        ping_compression_method);
22620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    PNG interlace_method: %d, filter_method: %d",
2265faa852bad40107edae19405e76a299057668d795glennrp        ping_interlace_method,ping_filter_method);
22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2268faa852bad40107edae19405e76a299057668d795glennrp#ifdef PNG_READ_iCCP_SUPPORTED
2269faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
22703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
22713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
22723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        compression;
22733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2274e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
2275e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_charp
2276e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2277e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
2278e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp      png_bytep
2279e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp        info;
2280e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
2281e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp
22823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_charp
22833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        name;
22843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_uint_32
22863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        profile_length;
22873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_iCCP(ping,ping_info,&name,(int *) &compression,&info,
22893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &profile_length);
22900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
22913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (profile_length != 0)
22923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
22933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          StringInfo
22943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *profile;
22953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
22973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
22983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG iCCP chunk.");
22993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=AcquireStringInfo(profile_length);
23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetStringInfoDatum(profile,(const unsigned char *) info);
23013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) SetImageProfile(image,"icc",profile);
23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          profile=DestroyStringInfo(profile);
23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sRGB_SUPPORTED)
23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->have_global_srgb)
2309cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
2310cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        (mng_info->global_srgb_intent);
23110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (png_get_sRGB(ping,ping_info,&intent))
23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
2314cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        image->rendering_intent=Magick_RenderingIntent_from_PNG_RenderingIntent
2315cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          (intent);
23160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2319e610a071534e448c46460a5aa39ede33bf56b329glennrp            "    Reading PNG sRGB chunk: rendering_intent: %d",intent);
23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
23213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
23223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
2324faa852bad40107edae19405e76a299057668d795glennrp     if (!png_get_gAMA(ping,ping_info,&file_gamma))
2325faa852bad40107edae19405e76a299057668d795glennrp       if (mng_info->have_global_gama)
2326faa852bad40107edae19405e76a299057668d795glennrp         png_set_gAMA(ping,ping_info,mng_info->global_gamma);
23270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (png_get_gAMA(ping,ping_info,&file_gamma))
23293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
23303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->gamma=(float) file_gamma;
23313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
23323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             "    Reading PNG gAMA chunk: gamma: %f",file_gamma);
23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
23353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2336faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_cHRM))
2337faa852bad40107edae19405e76a299057668d795glennrp    {
2338faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_chrm != MagickFalse)
2339faa852bad40107edae19405e76a299057668d795glennrp        {
2340faa852bad40107edae19405e76a299057668d795glennrp          (void) png_set_cHRM(ping,ping_info,
2341faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.x,
2342faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.white_point.y,
2343faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.x,
2344faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.red_primary.y,
2345faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.x,
2346faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.green_primary.y,
2347faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.x,
2348faa852bad40107edae19405e76a299057668d795glennrp            mng_info->global_chrm.blue_primary.y);
2349faa852bad40107edae19405e76a299057668d795glennrp        }
2350faa852bad40107edae19405e76a299057668d795glennrp    }
23510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2352faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_cHRM(ping,ping_info,
23553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.x,
23563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.white_point.y,
23573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.x,
23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.red_primary.y,
23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.x,
23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.green_primary.y,
23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.x,
23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        &image->chromaticity.blue_primary.y);
23630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG cHRM chunk.");
23673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2369e610a071534e448c46460a5aa39ede33bf56b329glennrp  if (image->rendering_intent != UndefinedIntent)
23703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2371e610a071534e448c46460a5aa39ede33bf56b329glennrp      png_set_sRGB(ping,ping_info,
2372cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         Magick_RenderingIntent_to_PNG_RenderingIntent
2373cf002022280cc4dedb2748ad6f415aac1d44f530glennrp         (image->rendering_intent));
2374faa852bad40107edae19405e76a299057668d795glennrp      png_set_gAMA(ping,ping_info,0.45455f);
2375faa852bad40107edae19405e76a299057668d795glennrp      png_set_cHRM(ping,ping_info,
2376faa852bad40107edae19405e76a299057668d795glennrp                  0.6400f, 0.3300f, 0.3000f, 0.6000f,
2377faa852bad40107edae19405e76a299057668d795glennrp                  0.1500f, 0.0600f, 0.3127f, 0.3290f);
23783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_oFFs_SUPPORTED)
2380faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
23813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2382905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.x=(ssize_t) png_get_x_offset_pixels(ping, ping_info);
2383905ef80dad2c83a01a607533f7039528ca7766b9cristy      image->page.y=(ssize_t) png_get_y_offset_pixels(ping, ping_info);
23840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
23853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
23863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->page.x || image->page.y)
23873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2388e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "    Reading PNG oFFs chunk: x: %.20g, y: %.20g.",(double)
2389e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            image->page.x,(double) image->page.y);
23903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
23913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
23923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
2393faa852bad40107edae19405e76a299057668d795glennrp  if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs))
2394faa852bad40107edae19405e76a299057668d795glennrp    {
2395faa852bad40107edae19405e76a299057668d795glennrp      if (mng_info->have_global_phys)
2396faa852bad40107edae19405e76a299057668d795glennrp        {
2397faa852bad40107edae19405e76a299057668d795glennrp          png_set_pHYs(ping,ping_info,
2398faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_x_pixels_per_unit,
2399faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_y_pixels_per_unit,
2400faa852bad40107edae19405e76a299057668d795glennrp                       mng_info->global_phys_unit_type);
2401faa852bad40107edae19405e76a299057668d795glennrp        }
2402faa852bad40107edae19405e76a299057668d795glennrp    }
2403faa852bad40107edae19405e76a299057668d795glennrp
2404faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
24053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
24073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image resolution.
24083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
24093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_pHYs(ping,ping_info,&x_resolution,&y_resolution,
24100881b52ab4fee8427578a694081946c4c4e92b35cristy        &unit_type);
24110881b52ab4fee8427578a694081946c4c4e92b35cristy      image->x_resolution=(double) x_resolution;
24120881b52ab4fee8427578a694081946c4c4e92b35cristy      image->y_resolution=(double) y_resolution;
24130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (unit_type == PNG_RESOLUTION_METER)
24153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->units=PixelsPerCentimeterResolution;
24173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->x_resolution=(double) x_resolution/100.0;
24183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->y_resolution=(double) y_resolution/100.0;
24193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
24223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2423e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Reading PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
2424e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) x_resolution,(double) y_resolution,unit_type);
24253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
24263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2427823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
2428faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
24293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
24303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
24313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        number_colors;
24323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_colorp
24343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palette;
24353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
24370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((number_colors == 0) &&
2439faa852bad40107edae19405e76a299057668d795glennrp          ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE))
24403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
24413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->global_plte_length)
24423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
24433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_set_PLTE(ping,ping_info,mng_info->global_plte,
24443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (int) mng_info->global_plte_length);
24450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2446faa852bad40107edae19405e76a299057668d795glennrp              if (!png_get_valid(ping,ping_info,PNG_INFO_tRNS))
24473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_trns_length)
24483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
24493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->global_trns_length >
24503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte_length)
24513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) ThrowMagickException(&image->exception,
24523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        GetMagickModule(),CoderError,
24533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "global tRNS has more entries than global PLTE",
24543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        "`%s'",image_info->filename);
24553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    png_set_tRNS(ping,ping_info,mng_info->global_trns,
24563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (int) mng_info->global_trns_length,NULL);
24573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
2458bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
24593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (
24603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
24613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->have_saved_bkgd_index ||
24623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2463faa852bad40107edae19405e76a299057668d795glennrp                   png_get_valid(ping,ping_info,PNG_INFO_bKGD))
24643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
24653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_color_16
24663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         background;
24673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (mng_info->have_saved_bkgd_index)
24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        background.index=mng_info->saved_bkgd_index;
24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2472faa852bad40107edae19405e76a299057668d795glennrp                      if (png_get_valid(ping, ping_info, PNG_INFO_bKGD))
2473faa852bad40107edae19405e76a299057668d795glennrp                        background.index=ping_background->index;
24740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.red=(png_uint_16)
24763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].red;
24770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.green=(png_uint_16)
24793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].green;
24800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
24813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      background.blue=(png_uint_16)
24823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->global_plte[background.index].blue;
24830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2484c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                      background.gray=(png_uint_16)
2485c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        mng_info->global_plte[background.index].green;
2486c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
24873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      png_set_bKGD(ping,ping_info,&background);
24883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
24893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
24903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
24913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
24933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"No global PLTE in file","`%s'",
24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image_info->filename);
24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2498bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#ifdef PNG_READ_bKGD_SUPPORTED
2499faa852bad40107edae19405e76a299057668d795glennrp  if (mng_info->have_global_bkgd &&
2500faa852bad40107edae19405e76a299057668d795glennrp          (!png_get_valid(ping,ping_info,PNG_INFO_bKGD)))
25013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_info->mng_global_bkgd;
25020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2503faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2505bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      unsigned int
2506bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale;
2507bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp
25083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
25093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Set image background color.
25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG bKGD chunk.");
25140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2515bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp      /* Scale background components to 16-bit, then scale
2516bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       * to quantum depth
2517bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp       */
2518bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2519bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2520bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    raw ping_background=(%d,%d,%d).",ping_background->red,
2521bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            ping_background->green,ping_background->blue);
25222cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2523bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        bkgd_scale = 1;
25240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2525bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth == 1)
2526bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 255;
25270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2528bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 2)
2529bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 85;
25300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2531bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        else if (ping_bit_depth == 4)
2532bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale = 17;
25330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2534bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (ping_bit_depth <= 8)
2535bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp           bkgd_scale *= 257;
25362cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2537bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->red *= bkgd_scale;
2538bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->green *= bkgd_scale;
2539bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        ping_background->blue *= bkgd_scale;
25402cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2541bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2542bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          {
25432cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25442cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    bkgd_scale=%d.",bkgd_scale);
25450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25462cbb4489df0a2a31907769956f217d4b9d982bd0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25472cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              "    ping_background=(%d,%d,%d).",ping_background->red,
25482cbb4489df0a2a31907769956f217d4b9d982bd0glennrp              ping_background->green,ping_background->blue);
2549bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          }
25502cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2551bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.red=
2552faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->red);
25530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2554bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.green=
2555faa852bad40107edae19405e76a299057668d795glennrp            ScaleShortToQuantum(ping_background->green);
25560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2557bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        image->background_color.blue=
2558bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          ScaleShortToQuantum(ping_background->blue);
25590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
25604c08aed51c5899665ade97263692328eea4af106cristy        image->background_color.alpha=OpaqueAlpha;
25612cbb4489df0a2a31907769956f217d4b9d982bd0glennrp
2562bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp        if (logging != MagickFalse)
2563bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2564bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            "    image->background_color=(%.20g,%.20g,%.20g).",
2565bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.red,
2566bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.green,
2567bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp            (double) image->background_color.blue);
25683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2569bfd9e61977198bea7d1ba9bf432226c6de0c38beglennrp#endif /* PNG_READ_bKGD_SUPPORTED */
2570a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2571faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
25723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
25733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
2574a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        Image has a tRNS chunk.
25753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
25763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
25773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        max_sample;
25783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
257935ef824baa82511126ff0072ae30eee0da9c05a3cristy      size_t
258035ef824baa82511126ff0072ae30eee0da9c05a3cristy        one=1;
258135ef824baa82511126ff0072ae30eee0da9c05a3cristy
25823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
25833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "    Reading PNG tRNS chunk.");
25853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2586f9cca6af1ff9b913c32a2cec81eda059877a8832cristy      max_sample = (int) ((one << ping_bit_depth) - 1);
25873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2588faa852bad40107edae19405e76a299057668d795glennrp      if ((ping_color_type == PNG_COLOR_TYPE_GRAY &&
2589faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->gray > max_sample) ||
2590faa852bad40107edae19405e76a299057668d795glennrp          (ping_color_type == PNG_COLOR_TYPE_RGB &&
2591faa852bad40107edae19405e76a299057668d795glennrp          ((int)ping_trans_color->red > max_sample ||
2592faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->green > max_sample ||
2593faa852bad40107edae19405e76a299057668d795glennrp          (int)ping_trans_color->blue > max_sample)))
25943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
25963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
25973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Ignoring PNG tRNS chunk with out-of-range sample.");
25983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_free_data(ping, ping_info, PNG_FREE_TRNS, 0);
2599faa852bad40107edae19405e76a299057668d795glennrp          png_set_invalid(ping,ping_info,PNG_INFO_tRNS);
26003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->matte=MagickFalse;
26013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
26033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2604a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          int
2605a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             scale_to_short;
2606a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2607a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          scale_to_short = 65535L/((1UL << ping_bit_depth)-1);
2608a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2609a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          /* Scale transparent_color to short */
2610a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.red= scale_to_short*ping_trans_color->red;
2611a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.green= scale_to_short*ping_trans_color->green;
2612a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          transparent_color.blue= scale_to_short*ping_trans_color->blue;
26134c08aed51c5899665ade97263692328eea4af106cristy          transparent_color.alpha= scale_to_short*ping_trans_color->gray;
261405eb4a94b088c7f75605e7c1ec06bd13a6b34a3fglennrp
2615faa852bad40107edae19405e76a299057668d795glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY)
26163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
26170f111984738842d27d04aed2a3f823d82a943506glennrp              if (logging != MagickFalse)
26180f111984738842d27d04aed2a3f823d82a943506glennrp              {
26190f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26200f111984738842d27d04aed2a3f823d82a943506glennrp                  "    Raw tRNS graylevel is %d.",ping_trans_color->gray);
26210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26220f111984738842d27d04aed2a3f823d82a943506glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26234c08aed51c5899665ade97263692328eea4af106cristy                  "    scaled graylevel is %d.",transparent_color.alpha);
26240f111984738842d27d04aed2a3f823d82a943506glennrp              }
26254c08aed51c5899665ade97263692328eea4af106cristy              transparent_color.red=transparent_color.alpha;
26264c08aed51c5899665ade97263692328eea4af106cristy              transparent_color.green=transparent_color.alpha;
26274c08aed51c5899665ade97263692328eea4af106cristy              transparent_color.blue=transparent_color.alpha;
26283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
26293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_READ_sBIT_SUPPORTED)
26323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->have_global_sbit)
26333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2634faa852bad40107edae19405e76a299057668d795glennrp      if (!png_get_valid(ping,ping_info,PNG_INFO_sBIT))
26353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_set_sBIT(ping,ping_info,&mng_info->global_sbit);
26363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
26383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
2639faa852bad40107edae19405e76a299057668d795glennrp
26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_read_update_info(ping,ping_info);
2641faa852bad40107edae19405e76a299057668d795glennrp
2642faa852bad40107edae19405e76a299057668d795glennrp  ping_rowbytes=png_get_rowbytes(ping,ping_info);
2643faa852bad40107edae19405e76a299057668d795glennrp
26443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
26463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
26473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.left=0;
2648bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.right=(ssize_t) ping_width;
26493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_box.top=0;
2650bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  mng_info->image_box.bottom=(ssize_t) ping_height;
26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2653faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_width=ping_width;
2654faa852bad40107edae19405e76a299057668d795glennrp      mng_info->mng_height=ping_height;
26553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->frame=mng_info->image_box;
26563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->clip=mng_info->image_box;
26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
26603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
26613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=mng_info->y_off[mng_info->object_id];
26623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->compression=ZipCompression;
2665faa852bad40107edae19405e76a299057668d795glennrp  image->columns=ping_width;
2666faa852bad40107edae19405e76a299057668d795glennrp  image->rows=ping_height;
2667faa852bad40107edae19405e76a299057668d795glennrp  if (((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
2668faa852bad40107edae19405e76a299057668d795glennrp      ((int) ping_color_type == PNG_COLOR_TYPE_GRAY))
26693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2670befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      size_t
2671befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy        one;
2672befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
26733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=PseudoClass;
2674befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      one=1;
2675befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy      image->colors=one << ping_bit_depth;
26763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (MAGICKCORE_QUANTUM_DEPTH == 8)
26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->colors > 256)
267867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=256;
267967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
268067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp      if (image->colors > 65536L)
268167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        image->colors=65536L;
26823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
2683faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
26873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
26893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
26903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
26913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
2692bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          image->colors=(size_t) number_colors;
26930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
26943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
26953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
26963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "    Reading PNG PLTE chunk: number_colors: %d.",number_colors);
26973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
26983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == PseudoClass)
27013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
27033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Initialize image colormap.
27043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
27053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (AcquireImageColormap(image,image->colors) == MagickFalse)
27063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
27070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2708faa852bad40107edae19405e76a299057668d795glennrp      if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
27093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
27103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int
27113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            number_colors;
27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_colorp
27143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            palette;
27153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) png_get_PLTE(ping,ping_info,&palette,&number_colors);
27170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27186af6cf1a950b111ad0ac706269a703086693ba71glennrp          for (i=0; i < (ssize_t) number_colors; i++)
27193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
27203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=ScaleCharToQuantum(palette[i].red);
27213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=ScaleCharToQuantum(palette[i].green);
27223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=ScaleCharToQuantum(palette[i].blue);
27233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27246af6cf1a950b111ad0ac706269a703086693ba71glennrp
272567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          for ( ; i < (ssize_t) image->colors; i++)
27266af6cf1a950b111ad0ac706269a703086693ba71glennrp          {
27276af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].red=0;
27286af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].green=0;
27296af6cf1a950b111ad0ac706269a703086693ba71glennrp            image->colormap[i].blue=0;
27306af6cf1a950b111ad0ac706269a703086693ba71glennrp          }
27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
27320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
27343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
2735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          size_t
27363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            scale;
27373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2738faa852bad40107edae19405e76a299057668d795glennrp          scale=(QuantumRange/((1UL << ping_bit_depth)-1));
27390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (scale < 1)
27413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scale=1;
27420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=0; i < (ssize_t) image->colors; i++)
27443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
27453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].red=(Quantum) (i*scale);
27463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].green=(Quantum) (i*scale);
27473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->colormap[i].blue=(Quantum) (i*scale);
27483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
27503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2751147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2752cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set some properties for reporting by "identify" */
2753cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp    {
2754147bc91f6859c598c4f57b6a162111b2f63614d9glennrp      char
2755147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        msg[MaxTextExtent];
2756147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
2757147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     /* encode ping_width, ping_height, ping_bit_depth, ping_color_type,
2758147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        ping_interlace_method in value */
2759147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27603b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,
27617cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp         "%d, %d",(int) ping_width, (int) ping_height);
27627cdb11cd177ff29a9d2d8503ad4c920b404eade4glennrp     (void) SetImageProperty(image,"PNG:IHDR.width,height    ",msg);
2763147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27643b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_bit_depth);
2765147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.bit_depth       ",msg);
2766147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27673b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",(int) ping_color_type);
2768147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.color_type      ",msg);
2769147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27703b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%d",
2771147bc91f6859c598c4f57b6a162111b2f63614d9glennrp        (int) ping_interlace_method);
2772147bc91f6859c598c4f57b6a162111b2f63614d9glennrp     (void) SetImageProperty(image,"PNG:IHDR.interlace_method",msg);
2773cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
2774147bc91f6859c598c4f57b6a162111b2f63614d9glennrp
27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
27763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image scanlines.
27773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
27783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->delay != 0)
27793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->scenes_found++;
27800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27810ca69b143ae83fb90449a01e0b0900cb83a1cbc8glennrp  if ((mng_info->mng_type == 0 && (image->ping != MagickFalse)) || (
2782347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->number_scenes != 0) && (mng_info->scenes_found > (ssize_t)
2783347e40f2829bd04656674c58927cc50cda195475glennrp      (image_info->first_scene+image_info->number_scenes))))
27843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
27853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2787e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Skipping PNG image data for scene %.20g",(double)
27883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->scenes_found-1);
27893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
27903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2791cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
27923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
27933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
27943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
27953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage().");
27960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
27973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
27983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
27990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading PNG IDAT chunk(s)");
28030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (num_passes > 1)
2805cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(image->rows,
2806cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_rowbytes*sizeof(*ping_pixels));
28070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
2809cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    ping_pixels=(unsigned char *) AcquireQuantumMemory(ping_rowbytes,
2810cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      sizeof(*ping_pixels));
28110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2812cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
28133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
28140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
28163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Converting PNG pixels to pixel packets");
28183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
28193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert PNG pixels to pixel packets.
28203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2821faa852bad40107edae19405e76a299057668d795glennrp  if (setjmp(png_jmpbuf(ping)))
28223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
28233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
28243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG image is corrupt.
28253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
28263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
28273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
2828cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
28293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
28303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
28313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info = DestroyQuantumInfo(quantum_info);
28320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2833cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
2834cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
28350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
28373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
28383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() with error.");
28390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
28417b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        {
28427b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          InheritException(exception,&image->exception);
28437b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy          image->columns=0;
28447b755eb4f94efbb57160cce0d7afe7f8ed4ef066cristy        }
28450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
28463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
28473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
28480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2849ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
28500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2851ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
2852ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
28530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2854c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  {
2855c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2856c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp   MagickBooleanType
2857c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp     found_transparent_pixel;
2858c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
2859c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp  found_transparent_pixel=MagickFalse;
2860c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
28613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->storage_class == DirectClass)
28623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2863c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (pass=0; pass < num_passes; pass++)
2864c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
2865c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        /*
2866c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          Convert image to DirectClass pixel packets.
2867c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        */
286867b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if  (MAGICKCORE_QUANTUM_DEPTH == 8)
286967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        int
287067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp          depth;
287167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp
287267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp        depth=(ssize_t) ping_bit_depth;
287367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
2874c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
2875c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
2876c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
2877c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            MagickTrue : MagickFalse;
28780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2879c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        for (y=0; y < (ssize_t) image->rows; y++)
2880c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
2881c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (num_passes > 1)
2882c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=ping_rowbytes*y;
28830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2884c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else
2885c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            row_offset=0;
28860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2887cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_read_row(ping,ping_pixels+row_offset,NULL);
2888c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
28893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2890acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy          if (q == (Quantum *) NULL)
2891c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
28920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2893c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY)
28943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2895cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayQuantum,ping_pixels+row_offset,exception);
28960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2897c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
28983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2899cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              GrayAlphaQuantum,ping_pixels+row_offset,exception);
29000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2901c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
29023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2903cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBAQuantum,ping_pixels+row_offset,exception);
29040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2905c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
2906c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2907cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              IndexQuantum,ping_pixels+row_offset,exception);
29080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2909c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          else /* ping_color_type == PNG_COLOR_TYPE_RGB */
2910c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2911cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              RGBQuantum,ping_pixels+row_offset,exception);
29123faa9a3fb01696daaf976d595f492cb530bffb21glennrp
2913c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (found_transparent_pixel == MagickFalse)
2914c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2915c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              /* Is there a transparent pixel in the row? */
2916a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp              if (y== 0 && logging != MagickFalse)
2917a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2918a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                   "    Looking for cheap transparent pixel");
2919a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2920c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              for (x=(ssize_t) image->columns-1; x >= 0; x--)
2921c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              {
29225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGBA ||
29235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) &&
29244c08aed51c5899665ade97263692328eea4af106cristy                   (GetPixelAlpha(image,q) != OpaqueAlpha))
2925c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  {
2926a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2927a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2928a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
2929a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
2930c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    found_transparent_pixel = MagickTrue;
2931c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    break;
2932c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  }
29334f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if ((ping_color_type == PNG_COLOR_TYPE_RGB ||
29344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_color_type == PNG_COLOR_TYPE_GRAY) &&
2935847370c32c6b67817205f49897c43c540fd670c4glennrp                    (ScaleQuantumToShort(GetPixelRed(image,q)) ==
2936847370c32c6b67817205f49897c43c540fd670c4glennrp                    transparent_color.red &&
2937847370c32c6b67817205f49897c43c540fd670c4glennrp                    ScaleQuantumToShort(GetPixelGreen(image,q)) ==
2938847370c32c6b67817205f49897c43c540fd670c4glennrp                    transparent_color.green &&
2939847370c32c6b67817205f49897c43c540fd670c4glennrp                    ScaleQuantumToShort(GetPixelBlue(image,q)) ==
2940847370c32c6b67817205f49897c43c540fd670c4glennrp                    transparent_color.blue))
29414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
2942a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                    if (logging != MagickFalse)
2943a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2944a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp                        "    ...got one.");
29454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    found_transparent_pixel = MagickTrue;
29464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    break;
29474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
2948ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
2949c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              }
2950c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
29510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2952c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if ((image->previous == (Image *) NULL) && (num_passes == 1))
2953c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            {
2954c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
2955c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                  image->rows);
29560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2957c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (status == MagickFalse)
2958c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                break;
2959c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            }
2960c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
2961c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            break;
2962c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
29630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2964c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if ((image->previous == (Image *) NULL) && (num_passes != 1))
29657a287bfadeadea12e47c2376ca78a5d101687142cristy          {
2966c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
29677a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
29687a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
29697a287bfadeadea12e47c2376ca78a5d101687142cristy          }
29703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
29713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
29720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else /* image->storage_class != DirectClass */
2974c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
29753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (pass=0; pass < num_passes; pass++)
29763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
29773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Quantum
29783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *quantum_scanline;
29793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register Quantum
29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *r;
29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
29833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
29843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Convert grayscale image to PseudoClass pixel packets.
29853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
2986c17d96f447438bb27d874f1440ed05f6493fde1fglennrp      if (logging != MagickFalse)
2987c17d96f447438bb27d874f1440ed05f6493fde1fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
2988c17d96f447438bb27d874f1440ed05f6493fde1fglennrp          "    Converting grayscale pixels to pixel packets");
29894c08aed51c5899665ade97263692328eea4af106cristy
2990faa852bad40107edae19405e76a299057668d795glennrp      image->matte=ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ?
29913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickTrue : MagickFalse;
29920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) AcquireQuantumMemory(image->columns,
29943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (image->matte ?  2 : 1)*sizeof(*quantum_scanline));
29950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
29963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_scanline == (Quantum *) NULL)
29973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
29980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
2999bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
30003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
30013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (num_passes > 1)
3002faa852bad40107edae19405e76a299057668d795glennrp          row_offset=ping_rowbytes*y;
3003c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
30043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
30053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          row_offset=0;
3006c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3007cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        png_read_row(ping,ping_pixels+row_offset,NULL);
30083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
30090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3010acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
30113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
30120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3013cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        p=ping_pixels+row_offset;
30143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
3015c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3016faa852bad40107edae19405e76a299057668d795glennrp        switch (ping_bit_depth)
30173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
30183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 1:
30193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3020bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            register ssize_t
30213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              bit;
30223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3023bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-7; x > 0; x-=8)
30243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
30253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (bit=7; bit >= 0; bit--)
3026a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
30273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              p++;
30283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 8) != 0)
30313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3032bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
3033a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                  *r++=(Quantum) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
30343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
30373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
303847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 2:
30403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3041bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-3; x > 0; x-=4)
30423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3043a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 6) & 0x03;
3044a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 4) & 0x03;
3045a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 2) & 0x03;
3046a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++) & 0x03;
30473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 4) != 0)
30503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3051bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
3052a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                  *r++=(Quantum) ((*p >> (i*2)) & 0x03);
30533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
30563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
305747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 4:
30593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3060bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x > 0; x-=2)
30613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
3062a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p >> 4) & 0x0f;
3063a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++) & 0x0f;
30643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
30650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((image->columns % 2) != 0)
3067a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp              *r++=(*p++ >> 4) & 0x0f;
30680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
30703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
307147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 8:
30733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3074faa852bad40107edae19405e76a299057668d795glennrp            if (ping_color_type == 4)
3075bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
30763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
3077a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
30784c08aed51c5899665ade97263692328eea4af106cristy                SetPixelAlpha(image,ScaleCharToQuantum((unsigned char) *p++),q);
30794c08aed51c5899665ade97263692328eea4af106cristy                if (GetPixelAlpha(image,q) != OpaqueAlpha)
30800b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  found_transparent_pixel = MagickTrue;
3081ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
30823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
30830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
3085bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (x=(ssize_t) image->columns-1; x >= 0; x--)
3086a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp                *r++=*p++;
30870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
30883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
30893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
309047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
30913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case 16:
30923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3093bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (x=(ssize_t) image->columns-1; x >= 0; x--)
3094a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            {
3095c17d96f447438bb27d874f1440ed05f6493fde1fglennrp#if (MAGICKCORE_QUANTUM_DEPTH == 16) || (MAGICKCORE_QUANTUM_DEPTH == 32)
309658f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              size_t
309758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                quantum;
309858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
309958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (image->colors > 256)
3100c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=((*p++) << 8);
310158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
310258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              else
3103c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                quantum=0;
310458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
310558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              quantum|=(*p++);
3106c17d96f447438bb27d874f1440ed05f6493fde1fglennrp              *r=ScaleShortToQuantum(quantum);
310758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              r++;
31080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3109faa852bad40107edae19405e76a299057668d795glennrp              if (ping_color_type == 4)
31103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
3111c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  if (image->colors > 256)
3112c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=((*p++) << 8);
3113c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  else
3114c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                    quantum=0;
3115c17d96f447438bb27d874f1440ed05f6493fde1fglennrp
3116c17d96f447438bb27d874f1440ed05f6493fde1fglennrp                  quantum|=(*p++);
31174c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,ScaleShortToQuantum(quantum),q);
31184c08aed51c5899665ade97263692328eea4af106cristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
311958f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                    found_transparent_pixel = MagickTrue;
3120ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  q+=GetPixelChannels(image);
312158f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                }
312258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp
312358f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp#else /* MAGICKCORE_QUANTUM_DEPTH == 8 */
312458f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              *r++=(*p++);
312558f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              p++; /* strip low byte */
312647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
312758f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp              if (ping_color_type == 4)
312858f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                {
31294c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,*p++,q);
31304c08aed51c5899665ade97263692328eea4af106cristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
31310b206f5daa453dc1035db5890cabc899736dc2d0glennrp                    found_transparent_pixel = MagickTrue;
313258f77c7678f35e372fd218e4bb0b9cb8937daed7glennrp                  p++;
3133ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  q+=GetPixelChannels(image);
31343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
31353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
3136a18d5bc7daf77f267862e1dfeee6fa0e5e2ea6e8glennrp            }
313747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
314047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          default:
31423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
31443faa9a3fb01696daaf976d595f492cb530bffb21glennrp
31453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
31463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Transfer image scanline.
31473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
31483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        r=quantum_scanline;
31490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31504c08aed51c5899665ade97263692328eea4af106cristy        q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
31514c08aed51c5899665ade97263692328eea4af106cristy
3152acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
31534c08aed51c5899665ade97263692328eea4af106cristy          break;
3154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x++)
31554c08aed51c5899665ade97263692328eea4af106cristy        {
31564c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,*r++,q);
3157ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
31584c08aed51c5899665ade97263692328eea4af106cristy        }
31590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
31613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
31620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
31637a287bfadeadea12e47c2376ca78a5d101687142cristy        if ((image->previous == (Image *) NULL) && (num_passes == 1))
31647a287bfadeadea12e47c2376ca78a5d101687142cristy          {
3165cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy            status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
31669fff7b4fa7d657da7bfed66239982b85c6337de9cristy              image->rows);
316747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31687a287bfadeadea12e47c2376ca78a5d101687142cristy            if (status == MagickFalse)
31697a287bfadeadea12e47c2376ca78a5d101687142cristy              break;
31707a287bfadeadea12e47c2376ca78a5d101687142cristy          }
31713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
3172c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31737a287bfadeadea12e47c2376ca78a5d101687142cristy      if ((image->previous == (Image *) NULL) && (num_passes != 1))
31743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
31753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=SetImageProgress(image,LoadImageTag,pass,num_passes);
317647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
31773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (status == MagickFalse)
31783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
31793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3180c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
31813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_scanline=(Quantum *) RelinquishMagickMemory(quantum_scanline);
31823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3183c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3184c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    image->matte=found_transparent_pixel;
3185c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3186c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    if (logging != MagickFalse)
3187c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      {
3188c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (found_transparent_pixel != MagickFalse)
3189c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3190c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            "    Found transparent pixel");
3191c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        else
31925aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          {
31935aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
31945aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              "    No transparent pixel was found");
3195bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
31965aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type&=0x03;
31975aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          }
3198c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
3199c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    }
3200c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
3201b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
3202b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
32030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
32045c6f789db7a30bad01ace12b09ad9cd471339e94cristy  if (image->storage_class == PseudoClass)
32055c6f789db7a30bad01ace12b09ad9cd471339e94cristy    {
3206aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      MagickBooleanType
32075c6f789db7a30bad01ace12b09ad9cd471339e94cristy        matte;
32085c6f789db7a30bad01ace12b09ad9cd471339e94cristy
32095c6f789db7a30bad01ace12b09ad9cd471339e94cristy      matte=image->matte;
32105c6f789db7a30bad01ace12b09ad9cd471339e94cristy      image->matte=MagickFalse;
32115c6f789db7a30bad01ace12b09ad9cd471339e94cristy      (void) SyncImage(image);
3212aeb2cbc4eb61cc6a04744db1dc52f5319c466e29cristy      image->matte=matte;
32135c6f789db7a30bad01ace12b09ad9cd471339e94cristy    }
321447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32154eb3931feb349dd87142c78503b779228f3e1a0fglennrp  png_read_end(ping,end_info);
32163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->number_scenes != 0 && mng_info->scenes_found-1 <
3218bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      (ssize_t) image_info->first_scene && image->delay != 0)
32193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_read_struct(&ping,&ping_info,&end_info);
3221cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
32223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->colors=2;
32233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageBackgroundColor(image);
32243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3225cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
32263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
32273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
32283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
32293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  exit ReadOnePNGImage() early.");
32303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(image);
32313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
323247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3233faa852bad40107edae19405e76a299057668d795glennrp  if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
32343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
32353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ClassType
32363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        storage_class;
32373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
32383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
32393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Image has a transparent background.
32403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
32413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      storage_class=image->storage_class;
32423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickTrue;
3243c11cf6a442f3046940608a5743a68cc891deb13eglennrp
32443c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp/* Balfour fix from imagemagick discourse server, 5 Feb 2010 */
3245c11cf6a442f3046940608a5743a68cc891deb13eglennrp
32460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (storage_class == PseudoClass)
32470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
32480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
3249c11cf6a442f3046940608a5743a68cc891deb13eglennrp            {
32500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < ping_num_trans; x++)
32510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
32524c08aed51c5899665ade97263692328eea4af106cristy                 image->colormap[x].alpha =
32534c08aed51c5899665ade97263692328eea4af106cristy                   ScaleCharToQuantum((unsigned char)ping_trans_alpha[x]);
32540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
3255c11cf6a442f3046940608a5743a68cc891deb13eglennrp            }
325647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
32570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          else if (ping_color_type == PNG_COLOR_TYPE_GRAY)
32580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
32590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              for (x=0; x < (int) image->colors; x++)
32600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
32610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 if (ScaleQuantumToShort(image->colormap[x].red) ==
32624c08aed51c5899665ade97263692328eea4af106cristy                     transparent_color.alpha)
32630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 {
32644c08aed51c5899665ade97263692328eea4af106cristy                    image->colormap[x].alpha = (Quantum) TransparentAlpha;
32650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                 }
32660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
32670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
32680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) SyncImage(image);
32690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
327047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3271a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if 1 /* Should have already been done above, but glennrp problem P10
3272a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       * needs this.
3273a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp       */
32740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
32750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
32760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          for (y=0; y < (ssize_t) image->rows; y++)
32770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
32780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            image->storage_class=storage_class;
32790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
3280c11cf6a442f3046940608a5743a68cc891deb13eglennrp
3281acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy            if (q == (Quantum *) NULL)
32820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              break;
3283c11cf6a442f3046940608a5743a68cc891deb13eglennrp
32840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3285a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp            /* Caution: on a Q8 build, this does not distinguish between
3286a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             * 16-bit colors that differ only in the low byte
3287a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp             */
32880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            for (x=(ssize_t) image->columns-1; x >= 0; x--)
32890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            {
3290847370c32c6b67817205f49897c43c540fd670c4glennrp              if (ScaleQuantumToShort(GetPixelRed(image,q)) ==
3291847370c32c6b67817205f49897c43c540fd670c4glennrp                  transparent_color.red &&
3292847370c32c6b67817205f49897c43c540fd670c4glennrp                  ScaleQuantumToShort(GetPixelGreen(image,q)) ==
3293847370c32c6b67817205f49897c43c540fd670c4glennrp                  transparent_color.green &&
3294847370c32c6b67817205f49897c43c540fd670c4glennrp                  ScaleQuantumToShort(GetPixelBlue(image,q)) ==
3295847370c32c6b67817205f49897c43c540fd670c4glennrp                  transparent_color.blue)
32964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
32974c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,TransparentAlpha,q);
32984f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
32990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
330067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if 0 /* I have not found a case where this is needed. */
33010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              else
33024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
33034c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,q)=(Quantum) OpaqueAlpha;
33044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
3305a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
33060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3307ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy              q+=GetPixelChannels(image);
33080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
33090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
33110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               break;
3312c11cf6a442f3046940608a5743a68cc891deb13eglennrp          }
33130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
3314a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
3315c11cf6a442f3046940608a5743a68cc891deb13eglennrp
33163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->storage_class=DirectClass;
33173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33183c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
3319b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy  if ((ping_color_type == PNG_COLOR_TYPE_GRAY) ||
3320b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy      (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
3321b40fc46321caef77f32743c0dc22e9a4bcc88e71cristy    image->colorspace=GRAYColorspace;
332247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3323eb3b22a03f31af7f724573d8537cd91fca06ee41cristy  for (j = 0; j < 2; j++)
33244eb3931feb349dd87142c78503b779228f3e1a0fglennrp  {
33254eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (j == 0)
3326a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,ping_info,&text,&num_text) != 0 ?
3327a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
33284eb3931feb349dd87142c78503b779228f3e1a0fglennrp    else
3329a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      status = png_get_text(ping,end_info,&text,&num_text) != 0 ?
3330a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          MagickTrue : MagickFalse;
33313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33324eb3931feb349dd87142c78503b779228f3e1a0fglennrp    if (status != MagickFalse)
33334eb3931feb349dd87142c78503b779228f3e1a0fglennrp      for (i=0; i < (ssize_t) num_text; i++)
33344eb3931feb349dd87142c78503b779228f3e1a0fglennrp      {
33354eb3931feb349dd87142c78503b779228f3e1a0fglennrp        /* Check for a profile */
33360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33374eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (logging != MagickFalse)
33384eb3931feb349dd87142c78503b779228f3e1a0fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33394eb3931feb349dd87142c78503b779228f3e1a0fglennrp            "    Reading PNG text chunk");
33400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33414eb3931feb349dd87142c78503b779228f3e1a0fglennrp        if (memcmp(text[i].key, "Raw profile type ",17) == 0)
33424eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
33434eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) Magick_png_read_raw_profile(image,image_info,text,(int) i);
33444eb3931feb349dd87142c78503b779228f3e1a0fglennrp            num_raw_profiles++;
33454eb3931feb349dd87142c78503b779228f3e1a0fglennrp          }
33464eb3931feb349dd87142c78503b779228f3e1a0fglennrp
33474eb3931feb349dd87142c78503b779228f3e1a0fglennrp        else
33484eb3931feb349dd87142c78503b779228f3e1a0fglennrp          {
33494eb3931feb349dd87142c78503b779228f3e1a0fglennrp            char
33504eb3931feb349dd87142c78503b779228f3e1a0fglennrp              *value;
33514eb3931feb349dd87142c78503b779228f3e1a0fglennrp
33524eb3931feb349dd87142c78503b779228f3e1a0fglennrp            length=text[i].text_length;
33534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=(char *) AcquireQuantumMemory(length+MaxTextExtent,
33544eb3931feb349dd87142c78503b779228f3e1a0fglennrp              sizeof(*value));
33554eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (value == (char *) NULL)
33564eb3931feb349dd87142c78503b779228f3e1a0fglennrp              {
33574eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (void) ThrowMagickException(&image->exception,GetMagickModule(),
33584eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  ResourceLimitError,"MemoryAllocationFailed","`%s'",
33594eb3931feb349dd87142c78503b779228f3e1a0fglennrp                  image->filename);
33604eb3931feb349dd87142c78503b779228f3e1a0fglennrp                break;
33614eb3931feb349dd87142c78503b779228f3e1a0fglennrp              }
33624eb3931feb349dd87142c78503b779228f3e1a0fglennrp            *value='\0';
33634eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (void) ConcatenateMagickString(value,text[i].text,length+2);
33644eb3931feb349dd87142c78503b779228f3e1a0fglennrp
33654eb3931feb349dd87142c78503b779228f3e1a0fglennrp            /* Don't save "density" or "units" property if we have a pHYs
33664eb3931feb349dd87142c78503b779228f3e1a0fglennrp             * chunk
33674eb3931feb349dd87142c78503b779228f3e1a0fglennrp             */
33684eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (!png_get_valid(ping,ping_info,PNG_INFO_pHYs) ||
33694eb3931feb349dd87142c78503b779228f3e1a0fglennrp                (LocaleCompare(text[i].key,"density") != 0 &&
33704eb3931feb349dd87142c78503b779228f3e1a0fglennrp                LocaleCompare(text[i].key,"units") != 0))
33714eb3931feb349dd87142c78503b779228f3e1a0fglennrp               (void) SetImageProperty(image,text[i].key,value);
33723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
33734eb3931feb349dd87142c78503b779228f3e1a0fglennrp            if (logging != MagickFalse)
33743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
33754eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33764eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      length: %lu",(unsigned long) length);
33774eb3931feb349dd87142c78503b779228f3e1a0fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
33784eb3931feb349dd87142c78503b779228f3e1a0fglennrp                "      Keyword: %s",text[i].key);
33793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
33800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
33814eb3931feb349dd87142c78503b779228f3e1a0fglennrp            value=DestroyString(value);
338297f90e23c85b9c58387880125c29d8c99126f83aglennrp          }
33834eb3931feb349dd87142c78503b779228f3e1a0fglennrp      }
33844eb3931feb349dd87142c78503b779228f3e1a0fglennrp      num_text_total += num_text;
33853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
33863c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
33873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
33883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
33893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Store the object if necessary.
33903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
33913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (object_id && !mng_info->frozen[object_id])
33923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
33933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->ob[object_id] == (MngBuffer *) NULL)
33943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
33953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
33963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            create a new object buffer.
33973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
33983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]=(MngBuffer *)
339973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy            AcquireMagickMemory(sizeof(MngBuffer));
34000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] != (MngBuffer *) NULL)
34023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->image=(Image *) NULL;
34043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->reference_count=1;
34053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
34063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
340747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->ob[object_id] == (MngBuffer *) NULL) ||
34093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->frozen)
34103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id] == (MngBuffer *) NULL)
34123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
34133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"MemoryAllocationFailed","`%s'",
34143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->filename);
34150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->frozen)
34173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
34183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cannot overwrite frozen MNG object buffer",
34193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
34203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
34233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
34243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
34263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image=DestroyImage
34273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->ob[object_id]->image);
34280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->ob[object_id]->image=CloneImage(image,0,0,MagickTrue,
34303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
34310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->ob[object_id]->image != (Image *) NULL)
34333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->ob[object_id]->image->file=(FILE *) NULL;
34340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
34353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
34363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) ThrowMagickException(&image->exception,GetMagickModule(),
34373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ResourceLimitError,"Cloning image for object buffer failed",
34383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "`%s'",image->filename);
34390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3440faa852bad40107edae19405e76a299057668d795glennrp          if (ping_width > 250000L || ping_height > 250000L)
34413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_error(ping,"PNG Image dimensions are too large.");
34420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3443faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->width=ping_width;
3444faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->height=ping_height;
3445faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->color_type=ping_color_type;
3446faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->sample_depth=ping_bit_depth;
3447faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->interlace_method=ping_interlace_method;
3448faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->compression_method=
3449faa852bad40107edae19405e76a299057668d795glennrp             ping_compression_method;
3450faa852bad40107edae19405e76a299057668d795glennrp          mng_info->ob[object_id]->filter_method=ping_filter_method;
34510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3452faa852bad40107edae19405e76a299057668d795glennrp          if (png_get_valid(ping,ping_info,PNG_INFO_PLTE))
34533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
34543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              int
34553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                number_colors;
34563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_colorp
34583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                plte;
34593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
34603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
34613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Copy the PLTE to the object buffer.
34623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
34633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              png_get_PLTE(ping,ping_info,&plte,&number_colors);
34643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=number_colors;
34653c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
34663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              for (i=0; i < number_colors; i++)
34673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
34683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ob[object_id]->plte[i]=plte[i];
34693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
34703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
347147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
34723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
34733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->ob[object_id]->plte_length=0;
34743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
34753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
34763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
34770a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
34780a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp   /* Set image->matte to MagickTrue if the input colortype supports
34790a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * alpha or if a valid tRNS chunk is present, no matter whether there
34800a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    * is actual transparency present.
34810a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    */
34820a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp    image->matte=(((int) ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA) ||
34830a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        ((int) ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
34840a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        (png_get_valid(ping,ping_info,PNG_INFO_tRNS))) ?
34850a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp        MagickTrue : MagickFalse;
34860a55b4c577b5e63eca6f108dea6f5c42191f78acglennrp
3487cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   /* Set more properties for identify to retrieve */
3488cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   {
3489cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     char
3490cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       msg[MaxTextExtent];
3491cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
34924eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (num_text_total != 0)
3493cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
3494cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         /* libpng doesn't tell us whether they were tEXt, zTXt, or iTXt */
34953b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3496613276d97a7f0e40c1055f9ff5ddfcfa8896e20bglennrp            "%d tEXt/zTXt/iTXt chunks were found", num_text_total);
3497cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text                 ",msg);
3498cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3499cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3500cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (num_raw_profiles != 0)
3501cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       {
35023b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
3503cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp            "%d were found", num_raw_profiles);
3504cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp         (void) SetImageProperty(image,"PNG:text-encoded profiles",msg);
3505cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp       }
3506cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3507cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_cHRM))
35085961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
35093b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35105961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Chromaticity, above)");
35115961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) SetImageProperty(image,"PNG:cHRM                 ",msg);
35125961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
3513cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3514cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_bKGD))
35155961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       {
35163b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35175961225e531a5f26ae179c1d919582d5cdaa44bbglennrp            "chunk was found (see Background color, above)");
35185961225e531a5f26ae179c1d919582d5cdaa44bbglennrp         (void) SetImageProperty(image,"PNG:bKGD                 ",msg);
35195961225e531a5f26ae179c1d919582d5cdaa44bbglennrp       }
35205961225e531a5f26ae179c1d919582d5cdaa44bbglennrp
35213b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy     (void) FormatLocaleString(msg,MaxTextExtent,"%s",
35225961225e531a5f26ae179c1d919582d5cdaa44bbglennrp        "chunk was found");
3523cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
3524cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_iCCP))
3525cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp        (void) SetImageProperty(image,"PNG:iCCP                 ",msg);
3526cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35274eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_tRNS))
35284eb3931feb349dd87142c78503b779228f3e1a0fglennrp        (void) SetImageProperty(image,"PNG:tRNS                 ",msg);
35294eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35304eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_sRGB_SUPPORTED)
3531cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_sRGB))
35324eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35333b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
353407523c7d2e40370804c2036295571e4b6426f94dglennrp            "intent=%d (See Rendering intent)",
35354eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (int) intent);
35364eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:sRGB                 ",msg);
35374eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
35384eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
35394eb3931feb349dd87142c78503b779228f3e1a0fglennrp
35404eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_gAMA))
35414eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35423b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
354307523c7d2e40370804c2036295571e4b6426f94dglennrp            "gamma=%.8g (See Gamma, above)",
35444eb3931feb349dd87142c78503b779228f3e1a0fglennrp            file_gamma);
35454eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:gAMA                 ",msg);
35464eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
3547cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35484eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_pHYs_SUPPORTED)
3549cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp     if (png_get_valid(ping,ping_info,PNG_INFO_pHYs))
35504eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35513b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
355207523c7d2e40370804c2036295571e4b6426f94dglennrp            "x_res=%.10g, y_res=%.10g, units=%d",
35534eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) x_resolution,(double) y_resolution, unit_type);
35544eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:pHYs                 ",msg);
35554eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
35564eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
3557cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35584eb3931feb349dd87142c78503b779228f3e1a0fglennrp#if defined(PNG_oFFs_SUPPORTED)
35594eb3931feb349dd87142c78503b779228f3e1a0fglennrp     if (png_get_valid(ping,ping_info,PNG_INFO_oFFs))
35604eb3931feb349dd87142c78503b779228f3e1a0fglennrp       {
35613b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,"x_off=%.20g, y_off=%.20g",
35624eb3931feb349dd87142c78503b779228f3e1a0fglennrp            (double) image->page.x,(double) image->page.y);
35634eb3931feb349dd87142c78503b779228f3e1a0fglennrp         (void) SetImageProperty(image,"PNG:oFFs                 ",msg);
35644eb3931feb349dd87142c78503b779228f3e1a0fglennrp       }
35654eb3931feb349dd87142c78503b779228f3e1a0fglennrp#endif
35664eb3931feb349dd87142c78503b779228f3e1a0fglennrp
356707523c7d2e40370804c2036295571e4b6426f94dglennrp     if ((image->page.width != 0 && image->page.width != image->columns) ||
356807523c7d2e40370804c2036295571e4b6426f94dglennrp         (image->page.height != 0 && image->page.height != image->rows))
356907523c7d2e40370804c2036295571e4b6426f94dglennrp       {
35703b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(msg,MaxTextExtent,
357107523c7d2e40370804c2036295571e4b6426f94dglennrp            "width=%.20g, height=%.20g",
357207523c7d2e40370804c2036295571e4b6426f94dglennrp            (double) image->page.width,(double) image->page.height);
357307523c7d2e40370804c2036295571e4b6426f94dglennrp         (void) SetImageProperty(image,"PNG:vpAg                 ",msg);
357407523c7d2e40370804c2036295571e4b6426f94dglennrp       }
3575cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp   }
3576cb395ac9c5c50c2829a9988f95fd8aea7af82c00glennrp
35773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
35783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
35793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_read_struct(&ping,&ping_info,&end_info);
35813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3582cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
35833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
3584cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
35853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
35863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
35883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
35893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOnePNGImage()");
35900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
35913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
35923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* end of reading one PNG image */
35943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
35953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
35963ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
35973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
35983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
35993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
36003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
36013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
360321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
360421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
36053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
36063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
36083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
36093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
36113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
36123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ssize_t
36143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
36153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
36183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
36203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
362147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
36233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
36243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
362547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
36273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3628fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadPNGImage()");
36293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
36303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
36313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
363247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
36343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(FileOpenError,"UnableToOpenFile");
363547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Verify PNG signature.
36383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,8,(unsigned char *) magic_number);
364047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
3641dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  if (count < 8 || memcmp(magic_number,"\211PNG\r\n\032\n",8) != 0)
36423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
364347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
36463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
364873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
364947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
36513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
365247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
36543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
36553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
36563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
36573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
36583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
36593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
36603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
36613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOnePNGImage(mng_info,image_info,exception);
36623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
366347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
36653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (previous != (Image *) NULL)
36673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
36683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (previous->signature != MagickSignature)
36693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ThrowReaderException(CorruptImageError,"CorruptImage");
36700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
36723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
36733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
36740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
36763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error");
36780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
36803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
368147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
368347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0))
36853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
36873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
36883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadPNGImage() with error.");
36890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
36913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
369247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
36933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG24") == 0)
36943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(image,TrueColorType);
36963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
36973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
36980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
36993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"PNG32") == 0)
37003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) SetImageType(image,TrueColorMatteType);
37010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
370397f90e23c85b9c58387880125c29d8c99126f83aglennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
370497f90e23c85b9c58387880125c29d8c99126f83aglennrp        "  page.w: %.20g, page.h: %.20g,page.x: %.20g, page.y: %.20g.",
370597f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.width,(double) image->page.height,
370697f90e23c85b9c58387880125c29d8c99126f83aglennrp            (double) image->page.x,(double) image->page.y);
370797f90e23c85b9c58387880125c29d8c99126f83aglennrp
370897f90e23c85b9c58387880125c29d8c99126f83aglennrp  if (logging != MagickFalse)
37093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadPNGImage()");
37100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
37113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
37123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
37133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
37173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
37183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d O n e J N G I m a g e                                             %
37233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
37263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadOneJNGImage() reads a JPEG Network Graphics (JNG) image file
37293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (minus the 8-byte signature)  and returns it.  It allocates the memory
37303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
37313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
37323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
37343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadOneJNGImage method is:
37363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadOneJNGImage(MngInfo *mng_info, const ImageInfo *image_info,
37383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         ExceptionInfo *exception)
37393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
37413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o mng_info: Specifies a pointer to a MngInfo structure.
37433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
37453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
37473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
37483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
37493ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadOneJNGImage(MngInfo *mng_info,
37503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const ImageInfo *image_info, ExceptionInfo *exception)
37513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
37523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
37533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image,
37543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image,
37553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
37563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jng_image;
37573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
37593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *alpha_image_info,
37603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *color_image_info;
37613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37624383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
37634383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    logging;
37644383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
3765bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
37663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
37673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
37693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
37703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32
37723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_height,
37733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_width;
37743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_byte
37763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
37773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_sample_depth,
37783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_compression_method,
37793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_image_interlace_method,
37803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
37813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
37823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_filter_method,
37833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_interlace_method;
37843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37854c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
37863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *s;
37873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3788bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
37893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
37903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
37913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37924c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
37933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
37943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
37963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
37973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
37983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
37993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    read_JSEP,
38003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reading_idat,
38013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
38023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3803bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
38043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
38053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
38073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=8;
38083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=0;
38093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_height=0;
38103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_width=0;
38113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image=(Image *) NULL;
38123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=(Image *) NULL;
38133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  alpha_image_info=(ImageInfo *) NULL;
38143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=(ImageInfo *) NULL;
38153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
3817fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter ReadOneJNGImage()");
38183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=mng_info->image;
38200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38214c08aed51c5899665ade97263692328eea4af106cristy  if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
38223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
38233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
38243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Allocate next image structure.
38253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
38263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
38273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
38283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  AcquireNextImage()");
38290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      AcquireNextImage(image_info,image);
38310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (GetNextImageInList(image) == (Image *) NULL)
38333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
38340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=SyncNextImageInList(image);
38363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
38373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
38383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
38403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Signature bytes have already been read.
38413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
38423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  read_JSEP=MagickFalse;
38443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  reading_idat=MagickFalse;
38453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
38463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (;;)
38473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
38483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
38493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
38503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
38523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *chunk;
38533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned int
38553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count;
38563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
38583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Read a new JNG chunk.
38593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
38603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
38613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      2*GetBlobSize(image));
38620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
38643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
38650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[0]='\0';
38673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
38683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length=ReadBlobMSBLong(image);
38693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count=(unsigned int) ReadBlob(image,4,(unsigned char *) type);
38703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (logging != MagickFalse)
38723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3873e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Reading JNG chunk type %c%c%c%c, length: %.20g",
3874e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        type[0],type[1],type[2],type[3],(double) length);
38753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length > PNG_UINT_31_MAX || count == 0)
38773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
38780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=NULL;
38803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk=(unsigned char *) NULL;
388147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
38833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
38843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
38850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (chunk == (unsigned char *) NULL)
38873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
38880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
3889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (i=0; i < (ssize_t) length; i++)
38903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[i]=(unsigned char) ReadBlobByte(image);
38910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
38923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=chunk;
38933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
389447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
38953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) ReadBlobMSBLong(image);  /* read crc word */
38963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
38973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (skip_to_iend)
38983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
38993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
39003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
390147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
39033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
39043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JHDR,4) == 0)
39063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 16)
39083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3909bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
39103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
3911bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            jng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
39123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
39133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_color_type=p[8];
39143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_sample_depth=p[9];
39153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_compression_method=p[10];
39163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_image_interlace_method=p[11];
391747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->interlace=jng_image_interlace_method != 0 ? PNGInterlace :
39193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              NoInterlace;
392047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth=p[12];
39223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_compression_method=p[13];
39233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_filter_method=p[14];
39243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_interlace_method=p[15];
392547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
39273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
39283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3929f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_width);
393047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
3932f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                  "    jng_width:      %16lu",(unsigned long) jng_height);
393347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_color_type: %16d",jng_color_type);
393647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_sample_depth:      %3d",
39393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_sample_depth);
394047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_compression_method:%3d",
39433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_compression_method);
394447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_image_interlace_method:  %3d",
39473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_image_interlace_method);
394847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_sample_depth:      %3d",
39513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_sample_depth);
395247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_compression_method:%3d",
39553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_compression_method);
395647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_filter_method:     %3d",
39593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_filter_method);
396047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    jng_alpha_interlace_method:  %3d",
39633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  jng_alpha_interlace_method);
39643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
39653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
396647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
39683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
396947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
39713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
39723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((reading_idat == MagickFalse) && (read_JSEP == MagickFalse) &&
39753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ((memcmp(type,mng_JDAT,4) == 0) || (memcmp(type,mng_JdAA,4) == 0) ||
39763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (memcmp(type,mng_IDAT,4) == 0) || (memcmp(type,mng_JDAA,4) == 0)))
39773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
39783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
39793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o create color_image
39803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o open color_blob, attached to color_image
39813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           o if (color type has alpha)
39823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               open alpha_blob, attached to alpha_image
39833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
39843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
398573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        color_image_info=(ImageInfo *)AcquireMagickMemory(sizeof(ImageInfo));
398647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image_info == (ImageInfo *) NULL)
39883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
398947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
39903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        GetImageInfo(color_image_info);
39913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        color_image=AcquireImage(color_image_info);
39920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
39933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (color_image == (Image *) NULL)
39943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
39953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
39963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
39973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
39983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Creating color_blob.");
39990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AcquireUniqueFilename(color_image->filename);
40013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=OpenBlob(color_image_info,color_image,WriteBinaryBlobMode,
40023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          exception);
40030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
40053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return((Image *) NULL);
40063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((image_info->ping == MagickFalse) && (jng_color_type >= 12))
40083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image_info=(ImageInfo *)
401073bd4a51b419e914565bdf204bf1540dc4c8ee26cristy              AcquireMagickMemory(sizeof(ImageInfo));
40110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image_info == (ImageInfo *) NULL)
40133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
40140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            GetImageInfo(alpha_image_info);
40163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            alpha_image=AcquireImage(alpha_image_info);
40170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (alpha_image == (Image *) NULL)
40193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                alpha_image=DestroyImage(alpha_image);
40213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                ThrowReaderException(ResourceLimitError,
40223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "MemoryAllocationFailed");
40233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Creating alpha_blob.");
40280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) AcquireUniqueFilename(alpha_image->filename);
40303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=OpenBlob(alpha_image_info,alpha_image,WriteBinaryBlobMode,
40313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              exception);
40320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
40343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
40350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (jng_alpha_compression_method == 0)
40373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
40383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                unsigned char
40393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data[18];
40403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
40423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Writing IHDR chunk to alpha_blob.");
40440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,8,(const unsigned char *)
40463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "\211PNG\r\n\032\n");
40470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
40483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,13L);
40493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(data,mng_IHDR);
405003812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IHDR,13L);
40513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+4,jng_width);
40523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGLong(data+8,jng_height);
40533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[12]=jng_alpha_sample_depth;
40543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[13]=0; /* color_type gray */
40553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[14]=0; /* compression method 0 */
40563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[15]=0; /* filter_method 0 */
40573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data[16]=0; /* interlace_method 0 */
40583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(alpha_image,17,data);
40593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(alpha_image,crc32(0,data,17));
40603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
40613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
40623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        reading_idat=MagickTrue;
40633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JDAT,4) == 0)
40663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
406747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk to color_image->blob */
40683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
40703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Copying JDAT chunk data to color_blob.");
40723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(color_image,length,chunk);
407447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
40763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
407747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
40783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
40793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
40803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IDAT,4) == 0)
40823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        png_byte
40843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data[5];
40853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
408647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy IDAT header and chunk data to alpha_image->blob */
40873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
40883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
40893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
40903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
40913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
40923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying IDAT chunk data to alpha_blob.");
40933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4094bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            (void) WriteBlobMSBULong(alpha_image,(size_t) length);
40953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            PNGType(data,mng_IDAT);
409603812ae402fb53d548f0e1d7d14720768f803c2dglennrp            LogPNGChunk(logging,mng_IDAT,length);
40973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,4,data);
40983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
40993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlobMSBULong(alpha_image,
41003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              crc32(crc32(0,data,4),chunk,(uInt) length));
41013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((memcmp(type,mng_JDAA,4) == 0) || (memcmp(type,mng_JdAA,4) == 0))
41103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
411147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        /* Copy chunk data to alpha_image->blob */
41123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_info->ping == MagickFalse)
41143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
41163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
41173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Copying JDAA chunk data to alpha_blob.");
41183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(alpha_image,length,chunk);
41203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_JSEP,4) == 0)
41293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        read_JSEP=MagickTrue;
41310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
41333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_bKGD,4) == 0)
41393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 2)
41413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
41433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=image->background_color.red;
41443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=image->background_color.red;
41453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 6)
41483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.red=ScaleCharToQuantum(p[1]);
41503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.green=ScaleCharToQuantum(p[3]);
41513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color.blue=ScaleCharToQuantum(p[5]);
41523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
41530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_gAMA,4) == 0)
41593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 4)
41618182b0758e3429fb8dcd1700f09643fd4d80a41ccristy          image->gamma=((float) mng_get_long(p))*0.00001;
41620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
41633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_cHRM,4) == 0)
41683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 32)
41703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
41718182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.x=0.00001*mng_get_long(p);
41728182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.white_point.y=0.00001*mng_get_long(&p[4]);
41738182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.x=0.00001*mng_get_long(&p[8]);
41748182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.red_primary.y=0.00001*mng_get_long(&p[12]);
41758182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.x=0.00001*mng_get_long(&p[16]);
41768182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.green_primary.y=0.00001*mng_get_long(&p[20]);
41778182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.x=0.00001*mng_get_long(&p[24]);
41788182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->chromaticity.blue_primary.y=0.00001*mng_get_long(&p[28]);
41793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
418047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
41813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
41823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
41833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
41843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
41853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_sRGB,4) == 0)
41863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
41873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length == 1)
41883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4189e610a071534e448c46460a5aa39ede33bf56b329glennrp            image->rendering_intent=
4190cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
41913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->gamma=0.45455f;
41923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.x=0.6400f;
41933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.red_primary.y=0.3300f;
41943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.x=0.3000f;
41953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.green_primary.y=0.6000f;
41963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.x=0.1500f;
41973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.blue_primary.y=0.0600f;
41983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.x=0.3127f;
41993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->chromaticity.white_point.y=0.3290f;
42003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
420147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_oFFs,4) == 0)
42073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
42093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42105eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.x=(ssize_t) mng_get_long(p);
42115eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp            image->page.y=(ssize_t) mng_get_long(&p[4]);
42120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] != 0)
42143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x/=10000;
42163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y/=10000;
42173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
421947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_pHYs,4) == 0)
42273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
42283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > 8)
42293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
42308182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->x_resolution=(double) mng_get_long(p);
42318182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            image->y_resolution=(double) mng_get_long(&p[4]);
42323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((int) p[8] == PNG_RESOLUTION_METER)
42333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
42343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->units=PixelsPerCentimeterResolution;
42353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->x_resolution=image->x_resolution/100.0f;
42363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->y_resolution=image->y_resolution/100.0f;
42373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
42383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
42390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if 0
42453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_iCCP,4) == 0)
42463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4247fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp        /* To do: */
42483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
42493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
42523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
42533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
42543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (length)
42563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk=(unsigned char *) RelinquishMagickMemory(chunk);
42573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IEND,4))
42593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
42600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    break;
42623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
42633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* IEND found */
42663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
42683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Finish up reading image data:
42693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o read main image from color_blob.
42713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close color_blob.
42733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o if (color_type has alpha)
42753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is PNG
42763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadPNG
42773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if alpha_encoding is JPEG
42783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               read secondary image from alpha_blob via ReadJPEG
42793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o close alpha_blob.
42813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o copy intensity of secondary image into
42834c08aed51c5899665ade97263692328eea4af106cristy         alpha samples of main image.
42843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       o destroy the secondary image.
42863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
42873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(color_image);
428947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
42903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
42913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
42923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Reading jng_image from color_blob.");
42930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42943b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(color_image_info->filename,MaxTextExtent,"%s",
42953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    color_image->filename);
42960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
42973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info->ping=MagickFalse;   /* To do: avoid this */
42983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=ReadImage(color_image_info,exception);
42990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
43013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
43023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(color_image->filename);
43043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image=DestroyImage(color_image);
43053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  color_image_info=DestroyImageInfo(color_image_info);
43063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_image == (Image *) NULL)
43083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
43093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
43113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Copying jng_image pixels to main image.");
43130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->rows=jng_height;
43153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->columns=jng_width;
43160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4317bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
43183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
43193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s=GetVirtualPixels(jng_image,0,y,image->columns,1,&image->exception);
43203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
43214c08aed51c5899665ade97263692328eea4af106cristy    for (x=(ssize_t) image->columns; x != 0; x--)
43224c08aed51c5899665ade97263692328eea4af106cristy    {
43234c08aed51c5899665ade97263692328eea4af106cristy      SetPixelRed(image,GetPixelRed(jng_image,s),q);
43244c08aed51c5899665ade97263692328eea4af106cristy      SetPixelGreen(image,GetPixelGreen(jng_image,s),q);
43254c08aed51c5899665ade97263692328eea4af106cristy      SetPixelBlue(image,GetPixelBlue(jng_image,s),q);
4326ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(image);
4327ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      s+=GetPixelChannels(jng_image);
43284c08aed51c5899665ade97263692328eea4af106cristy    }
432947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
43313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
43323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
43330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_image=DestroyImage(jng_image);
43350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping == MagickFalse)
43373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
43383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (jng_color_type >= 12)
43393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
43403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_alpha_compression_method == 0)
43413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
43423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             png_byte
43433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               data[5];
43443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,0x00000000L);
43453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(data,mng_IEND);
434603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_IEND,0L);
43473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(alpha_image,4,data);
43483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(alpha_image,crc32(0,data,4));
43493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
43500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) CloseBlob(alpha_image);
43520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
43543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
43554c08aed51c5899665ade97263692328eea4af106cristy             "    Reading alpha from alpha_blob.");
43563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43573b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy         (void) FormatLocaleString(alpha_image_info->filename,MaxTextExtent,
43583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "%s",alpha_image->filename);
43593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
43603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         jng_image=ReadImage(alpha_image_info,exception);
43610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
4363bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy           for (y=0; y < (ssize_t) image->rows; y++)
43643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
43653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             s=GetVirtualPixels(jng_image,0,y,image->columns,1,
43664c08aed51c5899665ade97263692328eea4af106cristy               &image->exception);
43673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
436847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
43693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->matte != MagickFalse)
43704c08aed51c5899665ade97263692328eea4af106cristy               for (x=(ssize_t) image->columns; x != 0; x--)
43714c08aed51c5899665ade97263692328eea4af106cristy               {
43724c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
4373ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  q+=GetPixelChannels(image);
4374ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  s+=GetPixelChannels(jng_image);
43754c08aed51c5899665ade97263692328eea4af106cristy               }
43760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
43784c08aed51c5899665ade97263692328eea4af106cristy               for (x=(ssize_t) image->columns; x != 0; x--)
43793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
43804c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,GetPixelRed(jng_image,s),q);
43814c08aed51c5899665ade97263692328eea4af106cristy                  if (GetPixelAlpha(image,q) != OpaqueAlpha)
43823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->matte=MagickTrue;
4383ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  q+=GetPixelChannels(image);
4384ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  s+=GetPixelChannels(jng_image);
43853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
43860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
43873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (SyncAuthenticPixels(image,exception) == MagickFalse)
43883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               break;
43893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
43903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) RelinquishUniqueFileResource(alpha_image->filename);
43913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image=DestroyImage(alpha_image);
43923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         alpha_image_info=DestroyImageInfo(alpha_image_info);
43933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (jng_image != (Image *) NULL)
43943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           jng_image=DestroyImage(jng_image);
43953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
43963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
43973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
439847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Read the JNG image.  */
439947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
44003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->mng_type == 0)
44013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
44023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_width=jng_width;
44033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->mng_height=jng_height;
44043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
44050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.width == 0 && image->page.height == 0)
44070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
44080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.width=jng_width;
44090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.height=jng_height;
44100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
44110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->page.x == 0 && image->page.y == 0)
44130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
44140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.x=mng_info->x_off[mng_info->object_id];
44150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
44160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
44170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
44190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
44200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      image->page.y=mng_info->y_off[mng_info->object_id];
44210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
44220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image_found++;
44243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=SetImageProgress(image,LoadImagesTag,2*TellBlob(image),
44253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    2*GetBlobSize(image));
44260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
44283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
44293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit ReadOneJNGImage()");
44300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
44323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
44333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
44353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d J N G I m a g e                                                   %
44403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
44433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadJNGImage() reads a JPEG Network Graphics (JNG) image file
44463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  (including the 8-byte signature)  and returns it.  It allocates the memory
44473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  necessary for the new Image structure and returns a pointer to the new
44483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image.
44493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
44513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadJNGImage method is:
44533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadJNGImage(const ImageInfo *image_info, ExceptionInfo
44553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%         *exception)
44563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
44583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
44603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
44623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
44633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
44643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadJNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
44663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
44673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
44683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
44693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
44703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
447221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
447321f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
44743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
44753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
44773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
44783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
44803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    magic_number[MaxTextExtent];
44813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
44833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
44843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
44853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
44863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
44873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
44883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
44893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
44903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
44913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
44923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4493fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadJNGImage()");
44943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
44953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
44963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
44970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
44983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
44993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
45000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"JNG") != 0)
45023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
45030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
450447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Verify JNG signature.  */
450547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
450747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45083b8763efd02f5343a141d40636f6a8dfdc2c7682glennrp  if (count < 8 || memcmp(magic_number,"\213JNG\r\n\032\n",8) != 0)
45093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
45100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
451147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
451247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
451473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(*mng_info));
45150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
45173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
45180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
451947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
452047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
45223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
45233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
45253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous=image;
45263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=ReadOneJNGImage(mng_info,image_info,exception);
45273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
45280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image == (Image *) NULL)
45303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (IsImageObject(previous) != MagickFalse)
45323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
45333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CloseBlob(previous);
45343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) DestroyImageList(previous);
45353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
45360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
45383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
45400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
45423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
454447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
45453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns == 0 || image->rows == 0)
45463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
45473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
45483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
45493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "exit ReadJNGImage() with error");
45500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"CorruptImage");
45523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
45530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
45553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadJNGImage()");
45560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
45573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(image);
45583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
45593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
45603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45613ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
45623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
45633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
45643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    page_geometry[MaxTextExtent];
45653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
45673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image,
45683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *previous;
45693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45704383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  MagickBooleanType
457121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
457221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure;
45734383ec8c3c8811128f5a8a034d67c47db5e7e75acristy
45743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
45753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    first_mng_object,
45763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    object_id,
45773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    term_chunk_found,
45783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skip_to_iend;
45793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile ssize_t
45813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count=0;
45823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
45843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
45853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickOffsetType
45873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
45883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
45903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
45913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngBox
45933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_fb,
45943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    fb,
45953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous_fb;
45963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
45973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
45983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PixelPacket
45993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_color;
46003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
46033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
46043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
46063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
46073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
46093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    count;
46103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
46123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    loop_level;
46133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile short
46153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    skipping_loop;
46163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
46193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mandatory_back=0;
46203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
46233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
46243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_background_object=0,
46253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_type=0;   /* 0: PNG or JNG; 1: MNG; 2: MNG-LC; 3: MNG-VLC */
46273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4628bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
46293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_timeout,
46303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_timeout,
46313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_height,
46333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_width,
46343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
46363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
463738ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp  /* These delays are all measured in image ticks_per_second,
463838ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   * not in MNG ticks_per_second
463938ea08308f079e4d21ad8b8ac465dcc3e1d78458glennrp   */
4640bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
46413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default_frame_delay,
46423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay,
46433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_image_delay,
46443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    frame_delay,
46453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
46463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    insert_layers,
46473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
46483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_iterations=1,
46493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    simplicity=0,
46503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_height=0,
46513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    subframe_width=0;
46523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.top=0;
46543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.bottom=0;
46553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.left=0;
46563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb.right=0;
46573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.top=0;
46583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.bottom=0;
46593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.left=0;
46603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb.right=0;
46613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
466247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Open image file.  */
466347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
46653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
46663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image_info->filename);
46673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
46683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
4669fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter ReadMNGImage()");
46703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
46713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info=(MngInfo *) NULL;
46723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
46730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
46753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((Image *) NULL);
46760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickFalse;
46783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skipping_loop=(-1);
46793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
468047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
468147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Allocate a MngInfo structure.  */
468247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
468373bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
46840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
46853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
46863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
46870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
468847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  /* Initialize members of the MngInfo structure.  */
468947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
46903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
46913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
46923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
46933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
46943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(image_info->magick,"MNG") == 0)
46953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
46963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
46973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        magic_number[MaxTextExtent];
46983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
469947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Verify MNG signature.  */
47003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(size_t) ReadBlob(image,8,(unsigned char *) magic_number);
47013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (memcmp(magic_number,"\212MNG\r\n\032\n",8) != 0)
47023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
470347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
470447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp      /* Initialize some nonzero members of the MngInfo structure.  */
47053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (i=0; i < MNG_MAX_OBJECTS; i++)
47063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4707bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].right=(ssize_t) PNG_UINT_31_MAX;
4708bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        mng_info->object_clip[i].bottom=(ssize_t) PNG_UINT_31_MAX;
47093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
47103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->exists[0]=MagickTrue;
47113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
471247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  first_mng_object=MagickTrue;
47143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_type=0;
47153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  insert_layers=MagickFalse; /* should be False when converting or mogrifying */
47173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_delay=0;
47193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_frame_timeout=0;
47203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  frame_delay=0;
47213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_delay=1;
47223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->ticks_per_second=1UL*image->ticks_per_second;
47233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  object_id=0;
47243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  skip_to_iend=MagickFalse;
47253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  term_chunk_found=MagickFalse;
47263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
47273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mandatory_back=MagickFalse;
47293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
47313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_background_color=image->background_color;
47323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default_fb=mng_info->frame;
47343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  previous_fb=mng_info->frame;
47353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
47363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
47373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
47383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      type[MaxTextExtent];
47393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(image_info->magick,"MNG") == 0)
47413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
47423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        unsigned char
47433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          *chunk;
47443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
47463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Read a new chunk.
47473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
47483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        type[0]='\0';
47493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ConcatenateMagickString(type,"errr",MaxTextExtent);
47503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length=ReadBlobMSBLong(image);
47513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count=(size_t) ReadBlob(image,4,(unsigned char *) type);
47523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
47543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4755e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           "  Reading MNG chunk type %c%c%c%c, length: %.20g",
4756e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy           type[0],type[1],type[2],type[3],(double) length);
47573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length > PNG_UINT_31_MAX)
47593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=MagickFalse;
47600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 0)
47623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"CorruptImage");
47630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        p=NULL;
47653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) NULL;
47660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length)
47683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) AcquireQuantumMemory(length,sizeof(*chunk));
477047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (chunk == (unsigned char *) NULL)
47723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
477347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
4774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) length; i++)
47753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[i]=(unsigned char) ReadBlobByte(image);
477647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
47773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=chunk;
47783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ReadBlobMSBLong(image);  /* read crc word */
47813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
47823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(JNG_SUPPORTED)
47833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_JHDR,4) == 0)
47843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
47860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->jhdr_warning == 0)
47883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
47893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"JNGCompressNotSupported","`%s'",image->filename);
47900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->jhdr_warning++;
47923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
47933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
47943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DHDR,4) == 0)
47953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
47963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
47970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
47983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->dhdr_warning == 0)
47993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
48003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DeltaPNGNotSupported","`%s'",image->filename);
48010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->dhdr_warning++;
48033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MEND,4) == 0)
48053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
480647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
48073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (skip_to_iend)
48083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
48093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (memcmp(type,mng_IEND,4) == 0)
48103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skip_to_iend=MagickFalse;
48110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
48133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
48173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skip to IEND.");
48180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
48203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
48210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MHDR,4) == 0)
48233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4824bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
48253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[2] << 8) | p[3]);
48260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
4827bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->mng_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
48283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (p[6] << 8) | p[7]);
48290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
48313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4833e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG width: %.20g",(double) mng_info->mng_width);
48343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4835e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "  MNG height: %.20g",(double) mng_info->mng_height);
48363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=8;
48398182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            mng_info->ticks_per_second=(size_t) mng_get_long(p);
48400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->ticks_per_second == 0)
48423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=0;
48430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
48453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              default_frame_delay=1UL*image->ticks_per_second/
48463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->ticks_per_second;
48470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
48493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            simplicity=0;
48500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
48523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
48533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p+=16;
48548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                simplicity=(size_t) mng_get_long(p);
48553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_type=1;    /* Full MNG */
48580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 11) == 11))
48603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=2; /* LC */
48610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((simplicity != 0) && ((simplicity | 9) == 9))
48633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_type=3; /* VLC */
48640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
48663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type != 3)
48673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              insert_layers=MagickTrue;
48683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
48694c08aed51c5899665ade97263692328eea4af106cristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
48703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
487147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
48723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
48730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
48753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
48760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=SyncNextImageInList(image);
48783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
48793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
48803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
48813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->mng_width > 65535L) ||
48823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (mng_info->mng_height > 65535L))
48833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ThrowReaderException(ImageError,"WidthOrHeightExceedsLimit");
48840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48853b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy            (void) FormatLocaleString(page_geometry,MaxTextExtent,
4886e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "%.20gx%.20g+0+0",(double) mng_info->mng_width,(double)
4887f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              mng_info->mng_height);
48880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.left=0;
4890bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.right=(ssize_t) mng_info->mng_width;
48913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->frame.top=0;
4892bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            mng_info->frame.bottom=(ssize_t) mng_info->mng_height;
48933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=default_fb=previous_fb=mng_info->frame;
48940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=0; i < MNG_MAX_OBJECTS; i++)
48963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[i]=mng_info->frame;
48970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
48983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
48993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_TERM,4) == 0)
49033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            int
49053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
49063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
49083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
49093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=p[0];
49100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (repeat == 3)
49123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49138182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                final_delay=(png_uint_32) mng_get_long(&p[2]);
49148182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_iterations=(png_uint_32) mng_get_long(&p[6]);
49150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_iterations == PNG_UINT_31_MAX)
49173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_iterations=0;
49180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
49203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickTrue;
49213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
49243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
49263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "    repeat=%d",repeat);
49270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4929e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    final_delay=%.20g",(double) final_delay);
49300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4932e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                  "    image->iterations=%.20g",(double) image->iterations);
49333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
49373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
49383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_DEFI,4) == 0)
49393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
49403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
49413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"DEFI chunk found in MNG-VLC datastream","`%s'",
49433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            object_id=(p[0] << 8) | p[1];
49460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 2 && object_id != 0)
49483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
49493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"Nonzero object_id in MNG-LC datastream","`%s'",
49503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
49510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (object_id > MNG_MAX_OBJECTS)
49533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
49553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Instead ofsuing a warning we should allocate a larger
49563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfo structure and continue.
49573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
49583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(&image->exception,GetMagickModule(),
49593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  CoderError,"object id too large","`%s'",image->filename);
49603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                object_id=MNG_MAX_OBJECTS;
49613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
49620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->exists[object_id])
49643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->frozen[object_id])
49653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
49663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk=(unsigned char *) RelinquishMagickMemory(chunk);
49673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
49683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    GetMagickModule(),CoderError,
49693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "DEFI cannot redefine a frozen MNG object","`%s'",
49703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->filename);
49713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
49723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
49730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->exists[object_id]=MagickTrue;
49750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 2)
49773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->invisible[object_id]=p[2];
49780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
49803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object offset info.
49813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
49823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
49833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
49840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->x_off[object_id]=(ssize_t) ((p[4] << 24) |
49850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[5] << 16) | (p[6] << 8) | p[7]);
49860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                mng_info->y_off[object_id]=(ssize_t) ((p[8] << 24) |
49880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    (p[9] << 16) | (p[10] << 8) | p[11]);
49890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
49913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
49923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4993e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  x_off[%d]: %.20g",object_id,(double)
4994f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->x_off[object_id]);
49950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
49963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
4997e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                      "  y_off[%d]: %.20g",object_id,(double)
4998f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                      mng_info->y_off[object_id]);
49993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
50003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
50033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Extract object clipping info.
50043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
50053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 27)
50063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->object_clip[object_id]=mng_read_box(mng_info->frame,0,
50073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                &p[12]);
50080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_bKGD,4) == 0)
50133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_global_bkgd=MagickFalse;
50150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 5)
50173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.red=
50193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
50200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.green=
50223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
50230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->mng_global_bkgd.blue=
50253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
50260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_bkgd=MagickTrue;
50283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
50333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BACK,4) == 0)
50343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
50353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
50363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
50373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=p[6];
50380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mandatory_back=0;
50410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mandatory_back && length > 5)
50433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.red=
50453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[0] << 8) | p[1]));
50460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.green=
50483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[2] << 8) | p[3]));
50490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_background_color.blue=
50513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    ScaleShortToQuantum((unsigned short) ((p[4] << 8) | p[5]));
50520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50534c08aed51c5899665ade97263692328eea4af106cristy                mng_background_color.alpha=OpaqueAlpha;
50543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
50573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
50583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_background_object=(p[7] << 8) | p[8];
50593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
50633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
506447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PLTE,4) == 0)
50663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
506747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global PLTE.  */
506847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
50693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length && (length < 769))
50703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
50713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->global_plte == (png_colorp) NULL)
50723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte=(png_colorp) AcquireQuantumMemory(256,
50733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    sizeof(*mng_info->global_plte));
50740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5075bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) (length/3); i++)
50763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
50773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].red=p[3*i];
50783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].green=p[3*i+1];
50793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->global_plte[i].blue=p[3*i+2];
50803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
50810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
508235ef824baa82511126ff0072ae30eee0da9c05a3cristy                mng_info->global_plte_length=(unsigned int) (length/3);
50833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
50843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
50853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
50863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
50873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].red=i;
50883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].green=i;
50893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte[i].blue=i;
50903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
50910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
50933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=256;
50943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
50953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
50963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_plte_length=0;
50970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
50983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
50993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
510147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_tRNS,4) == 0)
51033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* read global tRNS */
51053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 257)
5107bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy              for (i=0; i < (ssize_t) length; i++)
51083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_trns[i]=p[i];
51093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_LOOSE
51113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for ( ; i < 256; i++)
51123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->global_trns[i]=255;
51133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
511412560f31d66b4ef4afdcff2c20807c555dcf2f7dcristy            mng_info->global_trns_length=(unsigned int) length;
51153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_gAMA,4) == 0)
51193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 4)
51213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5122bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
51233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  igamma;
51243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51258182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                igamma=mng_get_long(p);
51263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_gamma=((float) igamma)*0.00001;
51273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_gama=MagickTrue;
51283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_gama=MagickFalse;
51320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
51333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
51363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_cHRM,4) == 0)
51383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
513947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read global cHRM */
514047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length == 32)
51423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
51438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.x=0.00001*mng_get_long(p);
51448182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.white_point.y=0.00001*mng_get_long(&p[4]);
51458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                mng_info->global_chrm.red_primary.x=0.00001*mng_get_long(&p[8]);
51463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.red_primary.y=0.00001*
51478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[12]);
51483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.x=0.00001*
51498182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[16]);
51503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.green_primary.y=0.00001*
51518182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[20]);
51523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.x=0.00001*
51538182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[24]);
51543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_chrm.blue_primary.y=0.00001*
51558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                  mng_get_long(&p[28]);
51563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_chrm=MagickTrue;
51573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_chrm=MagickFalse;
516047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
516447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sRGB,4) == 0)
51663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
51683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global sRGB.
51693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
51703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
51713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5172e610a071534e448c46460a5aa39ede33bf56b329glennrp                mng_info->global_srgb_intent=
5173cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_RenderingIntent_from_PNG_RenderingIntent(p[0]);
51743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_srgb=MagickTrue;
51753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
51763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
51773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_srgb=MagickFalse;
517847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
51803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
518247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_iCCP,4) == 0)
51843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5185fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* To do: */
51863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
51873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
51883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read global iCCP.
51893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
51903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
51913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
519247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
51943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
519547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
51963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_FRAM,4) == 0)
51973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
51983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_type == 3)
51993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
52003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"FRAM chunk found in MNG-VLC datastream","`%s'",
52013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
52020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->framing_mode == 2) || (mng_info->framing_mode == 4))
52043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image->delay=frame_delay;
52050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
52073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_timeout=default_frame_timeout;
52083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            fb=default_fb;
520947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
52113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (p[0])
52123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->framing_mode=p[0];
52130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
52153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "    Framing_mode=%d",mng_info->framing_mode);
52170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
52193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
522047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Note the delay and frame clipping boundaries.  */
522147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++; /* framing mode */
522347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5224bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                while (*p && ((p-chunk) < (ssize_t) length))
52253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  p++;  /* frame name */
522647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                p++;  /* frame name terminator */
522847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
5229bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                if ((p-chunk) < (ssize_t) (length-4))
52303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
52313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    int
52323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_delay,
52333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_timeout,
52343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      change_clipping;
52353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
52363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_delay=(*p++);
52373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_timeout=(*p++);
52383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    change_clipping=(*p++);
52393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    p++; /* change_sync */
524047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_delay)
52423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
52438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        frame_delay=1UL*image->ticks_per_second*
52448182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          mng_get_long(p);
52450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52468182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                        if (mng_info->ticks_per_second != 0)
52478182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                          frame_delay/=mng_info->ticks_per_second;
52480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5249bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5250bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_delay=PNG_UINT_31_MAX;
52510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
52533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_delay=frame_delay;
52540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
52560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
52583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5259e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_delay=%.20g",(double) frame_delay);
52603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
526147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_timeout)
52633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
5264bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        frame_timeout=1UL*image->ticks_per_second*
5265bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          mng_get_long(p);
52660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5267bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        if (mng_info->ticks_per_second != 0)
5268bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout/=mng_info->ticks_per_second;
52690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5270bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                        else
5271bb010dd620d8cf1743e64bc12f83e2bf1ffeddddglennrp                          frame_timeout=PNG_UINT_31_MAX;
52720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_delay == 2)
52743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_frame_timeout=frame_timeout;
52750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=4;
52770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
52793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5280e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            "    Framing_timeout=%.20g",(double) frame_timeout);
52813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
528247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (change_clipping)
52843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
52853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        fb=mng_read_box(previous_fb,(char) p[0],&p[1]);
52863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        p+=17;
52873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        previous_fb=fb;
52880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
52893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (logging != MagickFalse)
52903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
52910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                            "    Frame_clip: L=%.20g R=%.20g T=%.20g B=%.20g",
5292e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.left,(double) fb.right,(double) fb.top,
5293e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                            (double) fb.bottom);
529447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
52953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (change_clipping == 2)
52963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          default_fb=fb;
52973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
52983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
52993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=fb;
53013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clip=mng_minimum_box(fb,mng_info->frame);
53020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5303bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_width=(size_t) (mng_info->clip.right
53043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.left);
53050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
5306bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            subframe_height=(size_t) (mng_info->clip.bottom
53073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               -mng_info->clip.top);
53083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Insert a background layer behind the frame if framing_mode is 4.
53103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
53123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
53133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5314e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "   subframe_width=%.20g, subframe_height=%.20g",(double)
5315e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                subframe_width,(double) subframe_height);
53160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (insert_layers && (mng_info->framing_mode == 4) &&
53183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height))
53193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
532047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
53214c08aed51c5899665ade97263692328eea4af106cristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
53223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
532447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
53263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
53273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
53283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
53293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
53303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
533147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
53333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
53360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
53383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
53393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
53403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
53413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
53423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
53430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
53453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
53460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=subframe_width;
53483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=subframe_height;
53493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=subframe_width;
53503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=subframe_height;
53513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=mng_info->clip.left;
53523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=mng_info->clip.top;
53533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
53543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->matte=MagickFalse;
53553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
53563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
53570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
53583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
53593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
53600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                    "  Insert backgd layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5361e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.left,(double) mng_info->clip.right,
5362e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->clip.top,(double) mng_info->clip.bottom);
53633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
53643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
53653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLIP,4) == 0)
53693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            unsigned int
53713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
53723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
53733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
53753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Read CLIP.
53763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
53773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
53783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
537947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=(int) first_object; i <= (int) last_object; i++)
53813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
53823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
53833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
53843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngBox
53853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    box;
53863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
53873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  box=mng_info->object_clip[i];
53883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->object_clip[i]=mng_read_box(box,(char) p[4],&p[5]);
53893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
53903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
539147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
53923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
53933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
53943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
53953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SAVE,4) == 0)
53963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
53973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            for (i=1; i < MNG_MAX_OBJECTS; i++)
53983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i])
53993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 mng_info->frozen[i]=MagickTrue;
54013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
54023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 if (mng_info->ob[i] != (MngBuffer *) NULL)
54033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->ob[i]->frozen=MagickTrue;
54043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
54053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((memcmp(type,mng_DISC,4) == 0) || (memcmp(type,mng_SEEK,4) == 0))
54143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
541547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Read DISC or SEEK.  */
541647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((length == 0) || !memcmp(type,mng_SEEK,4))
54183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                for (i=1; i < MNG_MAX_OBJECTS; i++)
54203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
54213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5425bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                register ssize_t
54263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  j;
54273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5428bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (j=0; j < (ssize_t) length; j+=2)
54293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  i=p[j] << 8 | p[j+1];
54313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoDiscardObject(mng_info,i);
54323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
54363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
544047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MOVE,4) == 0)
54423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5443bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            size_t
54443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              first_object,
54453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              last_object;
54463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
544747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* read MOVE */
544847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            first_object=(p[0] << 8) | p[1];
54503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            last_object=(p[2] << 8) | p[3];
5451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=(ssize_t) first_object; i <= (ssize_t) last_object; i++)
54523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
54533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->exists[i] && !mng_info->frozen[i])
54543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
54553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
54563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    new_pair;
54573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngPair
54593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    old_pair;
54603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.a=mng_info->x_off[i];
54623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  old_pair.b=mng_info->y_off[i];
54633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  new_pair=mng_read_pair(old_pair,(int) p[4],&p[5]);
54643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->x_off[i]=new_pair.a;
54653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->y_off[i]=new_pair.b;
54663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
54673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
546847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
54693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
54723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
54733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_LOOP,4) == 0)
54743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5475bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            ssize_t loop_iters=1;
54763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
54773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_active[loop_level]=1;  /* mark loop active */
547847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
547947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            /* Record starting point.  */
54808182b0758e3429fb8dcd1700f09643fd4d80a41ccristy            loop_iters=mng_get_long(&chunk[1]);
54810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
54833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5484e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                "  LOOP level %.20g has %.20g iterations ",(double) loop_level,
5485e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) loop_iters);
54860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (loop_iters == 0)
54883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              skipping_loop=loop_level;
54890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
54913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
54923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_jump[loop_level]=TellBlob(image);
54933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->loop_count[loop_level]=loop_iters;
54943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
54950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
54963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->loop_iteration[loop_level]=0;
54973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
54983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
54993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
550047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_ENDL,4) == 0)
55023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            loop_level=chunk[0];
550447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (skipping_loop > 0)
55063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (skipping_loop == loop_level)
55083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
55103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Found end of zero-iteration loop.
55113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
55123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    skipping_loop=(-1);
55133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_active[loop_level]=0;
55143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
551647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
55193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (mng_info->loop_active[loop_level] == 1)
55203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
55213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_count[loop_level]--;
55223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    mng_info->loop_iteration[loop_level]++;
55230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (logging != MagickFalse)
55253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
55260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        "  ENDL: LOOP level %.20g has %.20g remaining iters ",
5527e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                        (double) loop_level,(double)
5528f2faecf9facdbbb14fcba373365f9f691a9658e0cristy                        mng_info->loop_count[loop_level]);
552947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (mng_info->loop_count[loop_level] != 0)
55313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        offset=SeekBlob(image,mng_info->loop_jump[loop_level],
55333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          SEEK_SET);
55340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        if (offset < 0)
55363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          ThrowReaderException(CorruptImageError,
55373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            "ImproperImageHeader");
55383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
553947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
55413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
55423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        short
55433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          last_level;
55443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        /*
55463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          Finished loop.
55473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        */
55483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        mng_info->loop_active[loop_level]=0;
55493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        last_level=(-1);
55503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        for (i=0; i < loop_level; i++)
55513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (mng_info->loop_active[i] == 1)
55523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            last_level=(short) i;
55533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        loop_level=last_level;
55543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
55553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
55563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
555747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
55593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
55603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
556147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_CLON,4) == 0)
55633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->clon_warning == 0)
55653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
55663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"CLON is not implemented yet","`%s'",
55673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
556847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->clon_warning++;
55703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
557147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
55723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_MAGN,4) == 0)
55733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
55743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_16
55753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first,
55763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last,
55773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb,
55783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml,
55793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr,
55803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt,
55813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx,
55823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my,
55833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx,
55843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy;
55853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
55863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 1)
55873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=(p[0] << 8) | p[1];
55880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_first=0;
55910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 3)
55933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=(p[2] << 8) | p[3];
55940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
55953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
55963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_last=magn_first;
55973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef MNG_OBJECT_BUFFERS
55983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first || magn_last)
55993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
56003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
56023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
56033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "MAGN is not implemented yet for nonzero objects",
56043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "`%s'",image->filename);
560547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
56073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 4)
56103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=p[4];
561147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methx=0;
56143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 6)
56163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=(p[5] << 8) | p[6];
561747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
562047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mx == 0)
56223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mx=1;
56233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
56253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=(p[7] << 8) | p[8];
562647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=magn_mx;
562947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_my == 0)
56313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_my=1;
56323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 10)
56343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=(p[9] << 8) | p[10];
563547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=magn_mx;
563847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_ml == 0)
56403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_ml=1;
56413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 12)
56433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=(p[11] << 8) | p[12];
564447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=magn_mx;
564747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mr == 0)
56493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mr=1;
56503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 14)
56523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=(p[13] << 8) | p[14];
565347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=magn_my;
565647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mt == 0)
56583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mt=1;
56593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 16)
56613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=(p[15] << 8) | p[16];
566247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=magn_my;
566547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_mb == 0)
56673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_mb=1;
56683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
56693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
56703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=p[17];
567147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
56733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              magn_methy=magn_methx;
56743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
567547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_methx > 5 || magn_methy > 5)
56773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->magn_warning == 0)
56783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
56793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) ThrowMagickException(&image->exception,
56803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     GetMagickModule(),CoderError,
56813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     "Unknown MAGN method in MNG datastream","`%s'",
56823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image->filename);
568347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
56843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   mng_info->magn_warning++;
56853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
56863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_OBJECT_BUFFERS
56873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Magnify existing objects in the range magn_first to magn_last */
56883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
56893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magn_first == 0 || magn_last == 0)
56903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
56913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Save the magnification factors for object 0 */
56923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mb=magn_mb;
56933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_ml=magn_ml;
56943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mr=magn_mr;
56953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mt=magn_mt;
56963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_mx=magn_mx;
56973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_my=magn_my;
56983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methx=magn_methx;
56993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->magn_methy=magn_methy;
57003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
57013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
570247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_PAST,4) == 0)
57043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->past_warning == 0)
57063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
57073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"PAST is not implemented yet","`%s'",
57083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
570947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->past_warning++;
57113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
571247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_SHOW,4) == 0)
57143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->show_warning == 0)
57163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
57173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"SHOW is not implemented yet","`%s'",
57183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
571947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->show_warning++;
57213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
572247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_sBIT,4) == 0)
57243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length < 4)
57263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_sbit=MagickFalse;
572747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.gray=p[0];
57313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.red=p[0];
57323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.green=p[1];
57333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.blue=p[2];
57343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_sbit.alpha=p[3];
57353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_sbit=MagickTrue;
57363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
57373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYs,4) == 0)
57393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 8)
57413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
57423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_x_pixels_per_unit=
57438182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(p);
57443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_y_pixels_per_unit=
57458182b0758e3429fb8dcd1700f09643fd4d80a41ccristy                    (size_t) mng_get_long(&p[4]);
57463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->global_phys_unit_type=p[8];
57473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_global_phys=MagickTrue;
57483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
574947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->have_global_phys=MagickFalse;
57523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_pHYg,4) == 0)
57543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->phyg_warning == 0)
57563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
57573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"pHYg is not implemented.","`%s'",image->filename);
575847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->phyg_warning++;
57603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
57613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_BASI,4) == 0)
57623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
57633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
576447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->basi_warning == 0)
57663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) ThrowMagickException(&image->exception,GetMagickModule(),
57673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                CoderError,"BASI is not implemented yet","`%s'",
57683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->filename);
576947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->basi_warning++;
57713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_BASI_SUPPORTED
5772bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_width=(size_t) ((p[0] << 24) | (p[1] << 16) |
57733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[2] << 8) | p[3]);
5774bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            basi_height=(size_t) ((p[4] << 24) | (p[5] << 16) |
57753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (p[6] << 8) | p[7]);
57763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_color_type=p[8];
57773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_compression_method=p[9];
57783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_filter_type=p[10];
57793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            basi_interlace_method=p[11];
57803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 11)
57813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=(p[12] << 8) & p[13];
578247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_red=0;
578547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 13)
57873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=(p[14] << 8) & p[15];
578847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_green=0;
579147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 15)
57933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=(p[16] << 8) & p[17];
579447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
57963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_blue=0;
579747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
57983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 17)
57993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_alpha=(p[18] << 8) & p[19];
580047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (basi_sample_depth == 16)
58043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=65535L;
58053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
58063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  basi_alpha=255;
58073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
580847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length > 19)
58103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=p[20];
581147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
58133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              basi_viewable=0;
581447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
581947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (memcmp(type,mng_IHDR,4)
58213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
58223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            && memcmp(type,mng_JHDR,4)
58233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            )
58253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* Not an IHDR or JHDR chunk */
58273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (length)
58283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk=(unsigned char *) RelinquishMagickMemory(chunk);
582947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Process IHDR */
58333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
58343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Processing %c%c%c%c chunk",type[0],type[1],type[2],type[3]);
583647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->exists[object_id]=MagickTrue;
58383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->viewable[object_id]=MagickTrue;
583947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->invisible[object_id])
58413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
58433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
58443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Skipping invisible object");
584547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            skip_to_iend=MagickTrue;
58473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
58493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
58503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
58513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (length < 8)
58523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
585347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58548182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_width=(size_t) mng_get_long(p);
58558182b0758e3429fb8dcd1700f09643fd4d80a41ccristy        image_height=(size_t) mng_get_long(&p[4]);
58563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
58573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        chunk=(unsigned char *) RelinquishMagickMemory(chunk);
58583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
58593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
58603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a transparent background layer behind the entire animation
58613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if it is not full screen.
58623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
58633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
58643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && mng_type && first_mng_object)
58653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
58663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((mng_info->clip.left > 0) || (mng_info->clip.top > 0) ||
58673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_width < mng_info->mng_width) ||
5868bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.right < (ssize_t) mng_info->mng_width) ||
58693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image_height < mng_info->mng_height) ||
5870bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (mng_info->clip.bottom < (ssize_t) mng_info->mng_height))
58713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
58724c08aed51c5899665ade97263692328eea4af106cristy                if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
58733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    /*
58753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      Allocate next image structure.
58763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    */
58773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    AcquireNextImage(image_info,image);
587847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (GetNextImageInList(image) == (Image *) NULL)
58803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      {
58813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        image=DestroyImageList(image);
58823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MngInfoFreeStruct(mng_info,&have_mng_structure);
58833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        return((Image *) NULL);
58843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      }
588547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=SyncNextImageInList(image);
58873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
58883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
588947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (term_chunk_found)
58913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
58923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickTrue;
58933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->iterations=mng_iterations;
58943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    term_chunk_found=MagickFalse;
58953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
589647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
58973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
58983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->start_loop=MagickFalse;
589947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
590047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Make a background rectangle.  */
590147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->delay=0;
59033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=mng_info->mng_width;
59043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=mng_info->mng_height;
59053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=mng_info->mng_width;
59063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=mng_info->mng_height;
59073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
59083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
59093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->background_color=mng_background_color;
59103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
59113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
59123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
5913e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "  Inserted transparent background layer, W=%.20g, H=%.20g",
5914e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    (double) mng_info->mng_width,(double) mng_info->mng_height);
59153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
59183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Insert a background layer behind the upcoming image if
59193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          framing_mode is 3, and we haven't already inserted one.
59203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
59213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (insert_layers && (mng_info->framing_mode == 3) &&
59223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (subframe_width) && (subframe_height) && (simplicity == 0 ||
59233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (simplicity & 0x08)))
59243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59254c08aed51c5899665ade97263692328eea4af106cristy            if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
59263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
59273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /*
59283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Allocate next image structure.
59293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              */
59303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              AcquireNextImage(image_info,image);
593147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetNextImageInList(image) == (Image *) NULL)
59333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
59343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  image=DestroyImageList(image);
59353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  MngInfoFreeStruct(mng_info,&have_mng_structure);
59363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  return((Image *) NULL);
59373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
593847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=SyncNextImageInList(image);
59403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
59410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->image=image;
59430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (term_chunk_found)
59453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickTrue;
59473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->iterations=mng_iterations;
59483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                term_chunk_found=MagickFalse;
59493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
59500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
59523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->start_loop=MagickFalse;
595347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=0;
59553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->columns=subframe_width;
59563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->rows=subframe_height;
59573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.width=subframe_width;
59583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.height=subframe_height;
59593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.x=mng_info->clip.left;
59603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->page.y=mng_info->clip.top;
59613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->background_color=mng_background_color;
59623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->matte=MagickFalse;
59633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) SetImageBackgroundColor(image);
59640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
59663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
59670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                "  Insert background layer, L=%.20g, R=%.20g T=%.20g, B=%.20g",
5968e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.left,(double) mng_info->clip.right,
5969e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                (double) mng_info->clip.top,(double) mng_info->clip.bottom);
59703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* MNG_INSERT_LAYERS */
59723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        first_mng_object=MagickFalse;
597347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59744c08aed51c5899665ade97263692328eea4af106cristy        if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
59753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
59773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Allocate next image structure.
59783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
59793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            AcquireNextImage(image_info,image);
598047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetNextImageInList(image) == (Image *) NULL)
59823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
59833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=DestroyImageList(image);
59843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                MngInfoFreeStruct(mng_info,&have_mng_structure);
59853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                return((Image *) NULL);
59863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
598747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
59883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image=SyncNextImageInList(image);
59893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
59903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->image=image;
59913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
59923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetBlobSize(image));
59930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
59953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
59960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
59973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (term_chunk_found)
59983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
59993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickTrue;
60003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            term_chunk_found=MagickFalse;
60013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
60043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->start_loop=MagickFalse;
60050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->framing_mode == 1 || mng_info->framing_mode == 3)
60073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image->delay=frame_delay;
60093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            frame_delay=default_frame_delay;
60103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
60110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
60133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image->delay=0;
60140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.width=mng_info->mng_width;
60163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.height=mng_info->mng_height;
60173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.x=mng_info->x_off[object_id];
60183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->page.y=mng_info->y_off[object_id];
60193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image->iterations=mng_iterations;
602047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
60223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Seek back to the beginning of the IHDR or JHDR chunk's length field.
60233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
602447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
60263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  Seeking back to beginning of %c%c%c%c chunk",type[0],type[1],
60283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            type[2],type[3]);
602947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6030bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        offset=SeekBlob(image,-((ssize_t) length+12),SEEK_CUR);
603147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (offset < 0)
60333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
60343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    previous=image;
60373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
60383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->mng_type=mng_type;
60393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->object_id=object_id;
60403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (memcmp(type,mng_IHDR,4) == 0)
60423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOnePNGImage(mng_info,image_info,exception);
604347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
60453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
60463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=ReadOneJNGImage(mng_info,image_info,exception);
60473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
60483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image == (Image *) NULL)
60503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
60513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (IsImageObject(previous) != MagickFalse)
60523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) DestroyImageList(previous);
60543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) CloseBlob(previous);
60553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
605647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
60583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
60593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image->columns == 0 || image->rows == 0)
60623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
60633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
60643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
60653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
60663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
60673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
60680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
60693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    mng_info->image=image;
60703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_type)
60723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
60733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngBox
60743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          crop_box;
60753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->magn_methx || mng_info->magn_methy)
60773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
60783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            png_uint_32
60793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_height,
60803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               magnified_width;
60813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
60833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
60843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Processing MNG MAGN chunk");
60853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
60863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methx == 1)
60873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
60883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width=mng_info->magn_ml;
608947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
60913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr;
609247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
609447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
609547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-2)*(mng_info->magn_mx));
60963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
609747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
60983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
60993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61004e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_width=(png_uint_32) image->columns;
610147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 1)
61033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_ml-1;
610447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 2)
61063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_width += mng_info->magn_mr-1;
610747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->columns > 3)
610947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_width += (png_uint_32)
611047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->columns-3)*(mng_info->magn_mx-1));
61113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
611247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->magn_methy == 1)
61143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_height=mng_info->magn_mt;
611647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
61183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb;
611947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
612147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
612247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-2)*(mng_info->magn_my));
61233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
612447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
61263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61274e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy                magnified_height=(png_uint_32) image->rows;
612847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 1)
61303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mt-1;
613147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 2)
61333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   magnified_height += mng_info->magn_mb-1;
613447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->rows > 3)
613647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   magnified_height += (png_uint_32)
613747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                      ((image->rows-3)*(mng_info->magn_my-1));
61383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
613947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (magnified_height > image->rows ||
61413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magnified_width > image->columns)
61423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
61433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
61443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *large_image;
61453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
61473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  yy;
61483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61494c08aed51c5899665ade97263692328eea4af106cristy                Quantum
61504c08aed51c5899665ade97263692328eea4af106cristy                  *next,
61514c08aed51c5899665ade97263692328eea4af106cristy                  *prev;
61524c08aed51c5899665ade97263692328eea4af106cristy
61534c08aed51c5899665ade97263692328eea4af106cristy                png_uint_16
61544c08aed51c5899665ade97263692328eea4af106cristy                  magn_methx,
61554c08aed51c5899665ade97263692328eea4af106cristy                  magn_methy;
61564c08aed51c5899665ade97263692328eea4af106cristy
6157bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                ssize_t
61583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  m,
61593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  y;
61603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61614c08aed51c5899665ade97263692328eea4af106cristy                register Quantum
61623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *n,
61633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *q;
61643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61654c08aed51c5899665ade97263692328eea4af106cristy                register ssize_t
61664c08aed51c5899665ade97263692328eea4af106cristy                  x;
61673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
616847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                /* Allocate next image structure.  */
616947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
61713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
61723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Allocate magnified image");
617347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                AcquireNextImage(image_info,image);
617547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
61763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (GetNextImageInList(image) == (Image *) NULL)
61773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image=DestroyImageList(image);
61793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    MngInfoFreeStruct(mng_info,&have_mng_structure);
61803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    return((Image *) NULL);
61813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
61823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image=SyncNextImageInList(image);
61843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->columns=magnified_width;
61863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                large_image->rows=magnified_height;
61873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methx=mng_info->magn_methx;
61893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                magn_methy=mng_info->magn_methy;
61903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
61913faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
61923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM unsigned short
61933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (magn_methx != 1 || magn_methy != 1)
61943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
61953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /*
61963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     Scale pixels to unsigned shorts to prevent
61973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     overflow of intermediate values of interpolations
61983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  */
6199bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (y=0; y < (ssize_t) image->rows; y++)
62003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
62013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       q=GetAuthenticPixels(image,0,y,image->columns,1,
62023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
620347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6204bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                       for (x=(ssize_t) image->columns-1; x >= 0; x--)
62053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       {
62064c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelRed(image,ScaleQuantumToShort(
62074c08aed51c5899665ade97263692328eea4af106cristy                            GetPixelRed(image,q)),q);
62084c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelGreen(image,ScaleQuantumToShort(
62094c08aed51c5899665ade97263692328eea4af106cristy                            GetPixelGreen(image,q)),q);
62104c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelBlue(image,ScaleQuantumToShort(
62114c08aed51c5899665ade97263692328eea4af106cristy                            GetPixelBlue(image,q)),q);
62124c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelAlpha(image,ScaleQuantumToShort(
62134c08aed51c5899665ade97263692328eea4af106cristy                            GetPixelAlpha(image,q)),q);
6214ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                          q+=GetPixelChannels(image);
62153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       }
621647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       if (SyncAuthenticPixels(image,exception) == MagickFalse)
62183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         break;
62193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
62203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
62223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define QM Quantum
62233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
62243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (image->matte != MagickFalse)
62263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (void) SetImageBackgroundColor(large_image);
622747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
62293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62304c08aed51c5899665ade97263692328eea4af106cristy                    large_image->background_color.alpha=OpaqueAlpha;
62313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) SetImageBackgroundColor(large_image);
623247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 4)
62343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=2;
623547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methx == 5)
62373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methx=3;
623847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 4)
62403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=2;
624147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (magn_methy == 5)
62433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      magn_methy=3;
62443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
62453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the rows into the right side of the large image */
62473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
62493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6250e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the rows to %.20g",(double) large_image->rows);
6251bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                m=(ssize_t) mng_info->magn_mt;
62523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                yy=0;
62533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=(size_t) image->columns;
62544c08aed51c5899665ade97263692328eea4af106cristy                next=(Quantum *) AcquireQuantumMemory(length,sizeof(*next));
62554c08aed51c5899665ade97263692328eea4af106cristy                prev=(Quantum *) AcquireQuantumMemory(length,sizeof(*prev));
625647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62574c08aed51c5899665ade97263692328eea4af106cristy                if ((prev == (Quantum *) NULL) ||
62584c08aed51c5899665ade97263692328eea4af106cristy                    (next == (Quantum *) NULL))
62593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     image=DestroyImageList(image);
62613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     MngInfoFreeStruct(mng_info,&have_mng_structure);
62623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     ThrowReaderException(ResourceLimitError,
62633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       "MemoryAllocationFailed");
62643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
626547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                n=GetAuthenticPixels(image,0,0,image->columns,1,exception);
62673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) CopyMagickMemory(next,n,length);
626847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6269bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
62703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
62713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (y == 0)
6272bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mt;
627347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6274bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-2)
6275bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
627647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6277bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy <= 1 && y == (ssize_t) image->rows-1)
6278bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_mb;
627947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6280bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  else if (magn_methy > 1 && y == (ssize_t) image->rows-1)
62813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    m=1;
628247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
6284bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    m=(ssize_t) mng_info->magn_my;
628547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  n=prev;
62873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  prev=next;
62883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  next=n;
628947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6290bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  if (y < (ssize_t) image->rows-1)
62913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
62923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      n=GetAuthenticPixels(image,0,y+1,image->columns,1,
62933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          exception);
62943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      (void) CopyMagickMemory(next,n,length);
62953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
629647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
62973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  for (i=0; i < m; i++, yy++)
62983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
62994c08aed51c5899665ade97263692328eea4af106cristy                    register Quantum
63003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      *pixels;
63013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    assert(yy < (ssize_t) large_image->rows);
63033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    pixels=prev;
63043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    n=next;
63053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q=GetAuthenticPixels(large_image,0,yy,large_image->columns,
63069fff7b4fa7d657da7bfed66239982b85c6337de9cristy                      1,exception);
63073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    q+=(large_image->columns-image->columns);
630847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6309bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    for (x=(ssize_t) image->columns-1; x >= 0; x--)
63103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
6311fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                      /* To do: get color as function of indexes[x] */
63123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      /*
63133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (image->storage_class == PseudoClass)
63143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
63153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
63163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      */
63173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
63183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methy <= 1)
63193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
6320bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          /* replicate previous */
63214c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelRed(large_image,GetPixelRed(image,pixels),q);
6322847370c32c6b67817205f49897c43c540fd670c4glennrp                          SetPixelGreen(large_image,GetPixelGreen(image,
6323847370c32c6b67817205f49897c43c540fd670c4glennrp                             pixels),q);
6324847370c32c6b67817205f49897c43c540fd670c4glennrp                          SetPixelBlue(large_image,GetPixelBlue(image,
6325847370c32c6b67817205f49897c43c540fd670c4glennrp                             pixels),q);
6326847370c32c6b67817205f49897c43c540fd670c4glennrp                          SetPixelAlpha(large_image,GetPixelAlpha(image,
6327847370c32c6b67817205f49897c43c540fd670c4glennrp                             pixels),q);
63283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
632947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methy == 2 || magn_methy == 4)
63313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
63323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6333bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            {
6334847370c32c6b67817205f49897c43c540fd670c4glennrp                              SetPixelRed(large_image,GetPixelRed(image,
6335847370c32c6b67817205f49897c43c540fd670c4glennrp                                 pixels),q);
6336847370c32c6b67817205f49897c43c540fd670c4glennrp                              SetPixelGreen(large_image,GetPixelGreen(image,
6337847370c32c6b67817205f49897c43c540fd670c4glennrp                                 pixels),q);
6338847370c32c6b67817205f49897c43c540fd670c4glennrp                              SetPixelBlue(large_image,GetPixelBlue(image,
6339847370c32c6b67817205f49897c43c540fd670c4glennrp                                 pixels),q);
6340847370c32c6b67817205f49897c43c540fd670c4glennrp                              SetPixelAlpha(large_image,GetPixelAlpha(image,
6341847370c32c6b67817205f49897c43c540fd670c4glennrp                                 pixels),q);
6342bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                            }
634347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
63453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
63463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
63474c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelRed(large_image,((QM) (((ssize_t)
63484c08aed51c5899665ade97263692328eea4af106cristy                                 (2*i*(GetPixelRed(image,n)
63494c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelRed(image,pixels)+m))/
6350bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
63514c08aed51c5899665ade97263692328eea4af106cristy                                 +GetPixelRed(image,pixels)))),q);
63524c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelGreen(large_image,((QM) (((ssize_t)
63534c08aed51c5899665ade97263692328eea4af106cristy                                 (2*i*(GetPixelGreen(image,n)
63544c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelGreen(image,pixels)+m))/
6355bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
63564c08aed51c5899665ade97263692328eea4af106cristy                                 +GetPixelGreen(image,pixels)))),q);
63574c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelBlue(large_image,((QM) (((ssize_t)
63584c08aed51c5899665ade97263692328eea4af106cristy                                 (2*i*(GetPixelBlue(image,n)
63594c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelBlue(image,pixels)+m))/
6360bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
63614c08aed51c5899665ade97263692328eea4af106cristy                                 +GetPixelBlue(image,pixels)))),q);
636247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
63644c08aed51c5899665ade97263692328eea4af106cristy                                 SetPixelAlpha(large_image, ((QM) (((ssize_t)
63654c08aed51c5899665ade97263692328eea4af106cristy                                    (2*i*(GetPixelAlpha(image,n)
63664c08aed51c5899665ade97263692328eea4af106cristy                                    -GetPixelAlpha(image,pixels)+m))
6367bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                    /((ssize_t) (m*2))+
63684c08aed51c5899665ade97263692328eea4af106cristy                                   GetPixelAlpha(image,pixels)))),q);
63693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
637047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 4)
63723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
63733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
63743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6375847370c32c6b67817205f49897c43c540fd670c4glennrp                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
6376847370c32c6b67817205f49897c43c540fd670c4glennrp                                    pixels),q);
63773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6378847370c32c6b67817205f49897c43c540fd670c4glennrp                                 SetPixelAlpha(large_image,GetPixelAlpha(image,
6379847370c32c6b67817205f49897c43c540fd670c4glennrp                                    n),q);
63803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
63813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
638247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methy == 3 || magn_methy == 5) */
63843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
63853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
63863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6387bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
6388847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelRed(large_image,GetPixelRed(image,
6389847370c32c6b67817205f49897c43c540fd670c4glennrp                                    pixels),q);
6390847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelGreen(large_image,GetPixelGreen(image,
6391847370c32c6b67817205f49897c43c540fd670c4glennrp                                    pixels),q);
6392847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelBlue(large_image,GetPixelBlue(image,
6393847370c32c6b67817205f49897c43c540fd670c4glennrp                                    pixels),q);
6394847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelAlpha(large_image,GetPixelAlpha(image,
6395847370c32c6b67817205f49897c43c540fd670c4glennrp                                    pixels),q);
6396bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
639747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
63983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6399bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
64004c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelRed(large_image,GetPixelRed(image,n),q);
6401847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelGreen(large_image,GetPixelGreen(image,n),
6402847370c32c6b67817205f49897c43c540fd670c4glennrp                                    q);
6403847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelBlue(large_image,GetPixelBlue(image,n),
6404847370c32c6b67817205f49897c43c540fd670c4glennrp                                    q);
6405847370c32c6b67817205f49897c43c540fd670c4glennrp                             SetPixelAlpha(large_image,GetPixelAlpha(image,n),
6406847370c32c6b67817205f49897c43c540fd670c4glennrp                                    q);
6407bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
640847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methy == 5)
64103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
64114c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelAlpha(large_image,(QM) (((ssize_t) (2*i*
64124c08aed51c5899665ade97263692328eea4af106cristy                                 (GetPixelAlpha(image,n)
64134c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelAlpha(image,pixels))
6414bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 +m))/((ssize_t) (m*2))
64154c08aed51c5899665ade97263692328eea4af106cristy                                 +GetPixelAlpha(image,pixels)),q);
64163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
64173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
6418ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                      n+=GetPixelChannels(image);
6419ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                      q+=GetPixelChannels(large_image);
6420ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                      pixels+=GetPixelChannels(image);
64213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    } /* x */
642247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    if (SyncAuthenticPixels(large_image,exception) == 0)
64243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
642547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  } /* i */
64273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                } /* y */
642847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64294c08aed51c5899665ade97263692328eea4af106cristy                prev=(Quantum *) RelinquishMagickMemory(prev);
64304c08aed51c5899665ade97263692328eea4af106cristy                next=(Quantum *) RelinquishMagickMemory(next);
64313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                length=image->columns;
64333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
64363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "    Delete original image");
64373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                DeleteImageFromList(&image);
64393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image=large_image;
64413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->image=image;
64433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* magnify the columns */
64453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
64463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6447e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Magnify the columns to %.20g",(double) image->columns);
64483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6449bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (y=0; y < (ssize_t) image->rows; y++)
64503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
64514c08aed51c5899665ade97263692328eea4af106cristy                  register Quantum
64523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *pixels;
64533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
64543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
6455ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  pixels=q+(image->columns-length)*GetPixelChannels(image);
6456ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                  n=pixels+GetPixelChannels(image);
645747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6458bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (x=(ssize_t) (image->columns-length);
6459bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    x < (ssize_t) image->columns; x++)
64603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
6461ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                    /* To do: Rewrite using Get/Set***PixelChannel() */
64627c7b31566a7598be23cac1b5e32c697cfe7082f4glennrp
6463bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    if (x == (ssize_t) (image->columns-length))
6464bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_ml;
646547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6466bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-2)
6467bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
646847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx <= 1 && x == (ssize_t) image->columns-1)
6470bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mr;
647147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6472bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                    else if (magn_methx > 1 && x == (ssize_t) image->columns-1)
64733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      m=1;
647447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    else
6476bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                      m=(ssize_t) mng_info->magn_mx;
647747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    for (i=0; i < m; i++)
64793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
64803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (magn_methx <= 1)
64813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* replicate previous */
64834c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelRed(image,GetPixelRed(image,pixels),q);
64844c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelGreen(image,GetPixelGreen(image,pixels),q);
64854c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelBlue(image,GetPixelBlue(image,pixels),q);
64864c08aed51c5899665ade97263692328eea4af106cristy                          SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
64873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
648847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
64893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else if (magn_methx == 2 || magn_methx == 4)
64903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
64913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i == 0)
6492bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
64934c08aed51c5899665ade97263692328eea4af106cristy                            SetPixelRed(image,GetPixelRed(image,pixels),q);
64944c08aed51c5899665ade97263692328eea4af106cristy                            SetPixelGreen(image,GetPixelGreen(image,pixels),q);
64954c08aed51c5899665ade97263692328eea4af106cristy                            SetPixelBlue(image,GetPixelBlue(image,pixels),q);
64964c08aed51c5899665ade97263692328eea4af106cristy                            SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6497bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
649847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6499ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                          /* To do: Rewrite using Get/Set***PixelChannel() */
65003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
65013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
65023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
65034c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelRed(image,(QM) ((2*i*(
65044c08aed51c5899665ade97263692328eea4af106cristy                                 GetPixelRed(image,n)
65054c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelRed(image,pixels))+m)
6506bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
65074c08aed51c5899665ade97263692328eea4af106cristy                                 GetPixelRed(image,pixels)),q);
6508bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
65094c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelGreen(image,(QM) ((2*i*(
65104c08aed51c5899665ade97263692328eea4af106cristy                                 GetPixelGreen(image,n)
65114c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelGreen(image,pixels))+m)
6512bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
65134c08aed51c5899665ade97263692328eea4af106cristy                                 GetPixelGreen(image,pixels)),q);
6514bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
65154c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelBlue(image,(QM) ((2*i*(
65164c08aed51c5899665ade97263692328eea4af106cristy                                 GetPixelBlue(image,n)
65174c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelBlue(image,pixels))+m)
6518bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 /((ssize_t) (m*2))+
65194c08aed51c5899665ade97263692328eea4af106cristy                                 GetPixelBlue(image,pixels)),q);
65203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (image->matte != MagickFalse)
65214c08aed51c5899665ade97263692328eea4af106cristy                                 SetPixelAlpha(image,(QM) ((2*i*(
65224c08aed51c5899665ade97263692328eea4af106cristy                                   GetPixelAlpha(image,n)
65234c08aed51c5899665ade97263692328eea4af106cristy                                   -GetPixelAlpha(image,pixels))+m)
6524bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                   /((ssize_t) (m*2))+
65254c08aed51c5899665ade97263692328eea4af106cristy                                   GetPixelAlpha(image,pixels)),q);
65263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
652747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 4)
65293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
65303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Replicate nearest */
65313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              if (i <= ((m+1) << 1))
6532bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
65334c08aed51c5899665ade97263692328eea4af106cristy                                 SetPixelAlpha(image,
65344c08aed51c5899665ade97263692328eea4af106cristy                                   GetPixelAlpha(image,pixels)+0,q);
6535bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
65363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              else
6537bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              {
65384c08aed51c5899665ade97263692328eea4af106cristy                                 SetPixelAlpha(image,
65394c08aed51c5899665ade97263692328eea4af106cristy                                   GetPixelAlpha(image,n)+0,q);
6540bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                              }
65413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
65423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
654347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      else /* if (magn_methx == 3 || magn_methx == 5) */
65453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        {
65463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          /* Replicate nearest */
65473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (i <= ((m+1) << 1))
6548bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
65494c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelRed(image,GetPixelRed(image,pixels),q);
65504c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelGreen(image,GetPixelGreen(image,pixels),q);
65514c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelBlue(image,GetPixelBlue(image,pixels),q);
65524c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelAlpha(image,GetPixelAlpha(image,pixels),q);
6553bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
655447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          else
6556bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          {
65574c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelRed(image,GetPixelRed(image,n),q);
65584c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelGreen(image,GetPixelGreen(image,n),q);
65594c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelBlue(image,GetPixelBlue(image,n),q);
65604c08aed51c5899665ade97263692328eea4af106cristy                             SetPixelAlpha(image,GetPixelAlpha(image,n),q);
6561bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                          }
656247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          if (magn_methx == 5)
65643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            {
65653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                              /* Interpolate */
65664c08aed51c5899665ade97263692328eea4af106cristy                              SetPixelAlpha(image,
65674c08aed51c5899665ade97263692328eea4af106cristy                                 (QM) ((2*i*( GetPixelAlpha(image,n)
65684c08aed51c5899665ade97263692328eea4af106cristy                                 -GetPixelAlpha(image,pixels))+m)/
6569bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                                 ((ssize_t) (m*2))
65704c08aed51c5899665ade97263692328eea4af106cristy                                 +GetPixelAlpha(image,pixels)),q);
65713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            }
65723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        }
6573ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                      q+=GetPixelChannels(image);
65743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
6575ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                    n+=GetPixelChannels(image);
6576ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                    p+=GetPixelChannels(image);
65773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
657847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
65793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (SyncAuthenticPixels(image,exception) == MagickFalse)
65803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    break;
65813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
65823faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
65833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (magn_methx != 1 || magn_methy != 1)
65843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
65853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
65863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   Rescale pixels to Quantum
65873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
6588bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                   for (y=0; y < (ssize_t) image->rows; y++)
65893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   {
65903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
659147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6592bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                     for (x=(ssize_t) image->columns-1; x >= 0; x--)
65933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     {
65944c08aed51c5899665ade97263692328eea4af106cristy                        SetPixelRed(image,ScaleShortToQuantum(
65954c08aed51c5899665ade97263692328eea4af106cristy                          GetPixelRed(image,q)),q);
65964c08aed51c5899665ade97263692328eea4af106cristy                        SetPixelGreen(image,ScaleShortToQuantum(
65974c08aed51c5899665ade97263692328eea4af106cristy                          GetPixelGreen(image,q)),q);
65984c08aed51c5899665ade97263692328eea4af106cristy                        SetPixelBlue(image,ScaleShortToQuantum(
65994c08aed51c5899665ade97263692328eea4af106cristy                          GetPixelBlue(image,q)),q);
66004c08aed51c5899665ade97263692328eea4af106cristy                        SetPixelAlpha(image,ScaleShortToQuantum(
66014c08aed51c5899665ade97263692328eea4af106cristy                          GetPixelAlpha(image,q)),q);
6602ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                        q+=GetPixelChannels(image);
66033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     }
660447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     if (SyncAuthenticPixels(image,exception) == MagickFalse)
66063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       break;
66073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   }
66083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
66093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
66113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    "  Finished MAGN processing");
66133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
66143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
66153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
66173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Crop_box is with respect to the upper left corner of the MNG.
66183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
66193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.left=mng_info->image_box.left+mng_info->x_off[object_id];
66203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.right=mng_info->image_box.right+mng_info->x_off[object_id];
66213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.top=mng_info->image_box.top+mng_info->y_off[object_id];
66223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box.bottom=mng_info->image_box.bottom+mng_info->y_off[object_id];
66233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->clip);
66243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->frame);
66253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        crop_box=mng_minimum_box(crop_box,mng_info->object_clip[object_id]);
66263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((crop_box.left != (mng_info->image_box.left
66273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
66283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.right != (mng_info->image_box.right
66293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->x_off[object_id])) ||
66303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.top != (mng_info->image_box.top
66313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])) ||
66323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (crop_box.bottom != (mng_info->image_box.bottom
66333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            +mng_info->y_off[object_id])))
66343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
66353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (logging != MagickFalse)
66363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
66373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                "  Crop the PNG image");
663847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((crop_box.left < crop_box.right) &&
66403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (crop_box.top < crop_box.bottom))
66413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
66423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Image
66433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *im;
66443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                RectangleInfo
66463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  crop_info;
66473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
66493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Crop_info is with respect to the upper left corner of
66503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the image.
66513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
66523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.x=(crop_box.left-mng_info->x_off[object_id]);
66533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                crop_info.y=(crop_box.top-mng_info->y_off[object_id]);
6654bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.width=(size_t) (crop_box.right-crop_box.left);
6655bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                crop_info.height=(size_t) (crop_box.bottom-crop_box.top);
66563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=image->columns;
66573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=image->rows;
66583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
66593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
66603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                im=CropImage(image,&crop_info,exception);
666147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (im != (Image *) NULL)
66633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
66643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->columns=im->columns;
66653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->rows=im->rows;
66663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    im=DestroyImage(im);
66673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.width=image->columns;
66683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.height=image->rows;
66693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.x=crop_box.left;
66703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    image->page.y=crop_box.top;
66713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
66723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
667347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
66743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
66753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
66763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
66773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  No pixels in crop area.  The MNG spec still requires
66783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  a layer, though, so make a single transparent pixel in
66793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  the top left corner.
66803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
66813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->columns=1;
66823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->rows=1;
66833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->colors=2;
66843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) SetImageBackgroundColor(image);
66853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.width=1;
66863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.height=1;
66873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.x=0;
66883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                image->page.y=0;
66893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
66903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
66913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifndef PNG_READ_EMPTY_PLTE_SUPPORTED
66923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=mng_info->image;
66933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
66943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
66953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66962b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
66972b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      /* PNG does not handle depths greater than 16 so reduce it even
66982b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       * if lossy
66992b013e4b9b602533eff410e61c3683fb2a3ab913glennrp       */
67002b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      if (image->depth > 16)
67012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp         image->depth=16;
67022b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
67032b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
67043faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
67058640fb5e9b1094f35f8beab436f81661b8a99448glennrp      if (LosslessReduceDepthOK(image) != MagickFalse)
67068640fb5e9b1094f35f8beab436f81661b8a99448glennrp         image->depth = 8;
67073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6708d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
67093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageException(image,exception);
671047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->number_scenes != 0)
67123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->scenes_found >
6714bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy             (ssize_t) (image_info->first_scene+image_info->number_scenes))
67153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
67163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
6717d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
67183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
67193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Finished reading image datastream.");
6721d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp
67223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (LocaleCompare(image_info->magick,"MNG") == 0);
672347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
672547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
67273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Finished reading all image datastreams.");
672947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MNG_INSERT_LAYERS)
67313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers && !mng_info->image_found && (mng_info->mng_width) &&
67323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (mng_info->mng_height))
67333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
67343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
67353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Insert a background layer if nothing else was found.
67363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
67373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
67383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No images found.  Inserting a background layer.");
67400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67414c08aed51c5899665ade97263692328eea4af106cristy      if (GetAuthenticPixelQueue(image) != (Quantum *) NULL)
67423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
67433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
67443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Allocate next image structure.
67453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
67463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          AcquireNextImage(image_info,image);
67473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetNextImageInList(image) == (Image *) NULL)
67483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
67493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image=DestroyImageList(image);
67503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MngInfoFreeStruct(mng_info,&have_mng_structure);
675147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (logging != MagickFalse)
67533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
67543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Allocation failed, returning NULL.");
675547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              return((Image *) NULL);
67573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
67583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image=SyncNextImageInList(image);
67593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
67603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->columns=mng_info->mng_width;
67613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->rows=mng_info->mng_height;
67623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.width=mng_info->mng_width;
67633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.height=mng_info->mng_height;
67643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.x=0;
67653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->page.y=0;
67663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->background_color=mng_background_color;
67673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte=MagickFalse;
67680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->ping == MagickFalse)
67703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) SetImageBackgroundColor(image);
67710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->image_found++;
67733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
67743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
67753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->iterations=mng_iterations;
67760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_iterations == 1)
67783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
67790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetPreviousImageInList(image) != (Image *) NULL)
67813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
67823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count++;
67833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_count > 10*mng_info->image_found)
67843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
67863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  No beginning");
678747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
67893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted, beginning of list not found",
67903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "`%s'",image_info->filename);
679147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
67923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return((Image *) NULL);
67933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
67940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=GetPreviousImageInList(image);
67960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
67973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
67983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
67993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (logging != MagickFalse)
68003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Corrupt list");
680147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ThrowMagickException(&image->exception,GetMagickModule(),
68033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          CoderError,"Linked list is corrupted; next_image is NULL","`%s'",
68043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info->filename);
68053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
68063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
680747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second && mng_info->image_found > 1 &&
68093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             GetNextImageInList(image) ==
68103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (Image *) NULL)
68113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "  First image null");
681547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
68173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"image->next for first image is NULL but shouldn't be.",
68183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "`%s'",image_info->filename);
68193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
682047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->image_found == 0)
68223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  No visible images found.");
682647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ThrowMagickException(&image->exception,GetMagickModule(),
68283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        CoderError,"No visible images in file","`%s'",image_info->filename);
682947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image != (Image *) NULL)
68313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=DestroyImageList(image);
683247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      MngInfoFreeStruct(mng_info,&have_mng_structure);
68343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
68353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->ticks_per_second)
68383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=1UL*MagickMax(image->ticks_per_second,1L)*
68393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/mng_info->ticks_per_second;
68400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
68423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image->start_loop=MagickTrue;
68430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Find final nonzero image delay */
68453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  final_image_delay=0;
68460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
68483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->delay)
68503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_image_delay=image->delay;
685147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
68533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (final_delay < final_image_delay)
68563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=final_image_delay;
68570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->delay=final_delay;
68590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
68613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6862e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  image->delay=%.20g, final_delay=%.20g",(double) image->delay,
6863e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) final_delay);
68640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
68653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
68663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
68683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
68693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
68713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
687247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
68743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Before coalesce:");
687547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6877e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g",(double) image->delay);
687847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
68793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
68803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
68813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetNextImageInList(image);
68823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6883e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g",(double) scene++,(double) image->delay);
68843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
68853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
68863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
68883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef MNG_COALESCE_LAYERS
68893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (insert_layers)
68903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
68913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
68923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next_image,
68933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *next;
68943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
68963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
68973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
68983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
68993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Coalesce Images");
690047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=image->scene;
69023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      next_image=CoalesceImages(image,&image->exception);
690347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (next_image == (Image *) NULL)
69053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
690647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
69083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=next_image;
690947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next=image; next != (Image *) NULL; next=next_image)
69113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
69123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.width=mng_info->mng_width;
69133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.height=mng_info->mng_height;
69143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.x=0;
69153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->page.y=0;
69163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next->scene=scene++;
69173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         next_image=GetNextImageInList(next);
691847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next_image == (Image *) NULL)
69203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           break;
692147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (next->delay == 0)
69233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
69243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             scene--;
69253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next_image->previous=GetPreviousImageInList(next);
69263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (GetPreviousImageInList(next) == (Image *) NULL)
69273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               image=next_image;
69283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
69293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               next->previous->next=next_image;
69303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             next=DestroyImage(next);
69313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
69323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
69333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
69343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetNextImageInList(image) != (Image *) NULL)
69373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetNextImageInList(image);
693847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->dispose=BackgroundDispose;
69403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
69433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
69443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        scene;
69453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
69473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=GetFirstImageInList(image);
694847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
69503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  After coalesce:");
695147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6953e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    scene 0 delay=%.20g dispose=%.20g",(double) image->delay,
6954e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) image->dispose);
695547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetNextImageInList(image) != (Image *) NULL)
6957f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      {
6958f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        image=GetNextImageInList(image);
695947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
6960f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
6961e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    scene %.20g delay=%.20g dispose=%.20g",(double) scene++,
6962e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          (double) image->delay,(double) image->dispose);
6963f2faecf9facdbbb14fcba373365f9f691a9658e0cristy      }
6964f2faecf9facdbbb14fcba373365f9f691a9658e0cristy   }
696547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=GetFirstImageInList(image);
69673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
69683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
696947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
69713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit ReadMNGImage()");
697247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
69743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
697525c1e2baba76d9cf3ec582f217f96af95259e747glennrp#else /* PNG_LIBPNG_VER > 10011 */
69763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
69773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
69783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
69793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
698047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
69823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "PNG library is too old","`%s'",image_info->filename);
698347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(Image *) NULL;
69853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
698647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
69873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadMNGImage(const ImageInfo *image_info,ExceptionInfo *exception)
69883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
69893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(ReadPNGImage(image_info,exception));
69903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
699125c1e2baba76d9cf3ec582f217f96af95259e747glennrp#endif /* PNG_LIBPNG_VER > 10011 */
69923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
69933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
69943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
69953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
69973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
69983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
69993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P N G I m a g e                                           %
70003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
70033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
70053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPNGImage() adds properties for the PNG image format to
70063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
70073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
70083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
70093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
70103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
70113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
70123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPNGImage method is:
70133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7014bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPNGImage(void)
70153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
70163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7017bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPNGImage(void)
70183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
70193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
70203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version[MaxTextExtent];
70213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
70233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
70243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static const char
70263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *PNGNote=
70273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/ for details about the PNG format."
70293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
703047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *JNGNote=
70323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the JNG\n"
70343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
70353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    },
703647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *MNGNote=
70383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "See http://www.libpng.org/pub/mng/ for details about the MNG\n"
70403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "format."
70413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    };
70423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
704447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_LIBPNG_VER_STRING)
70463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"libpng ",MaxTextExtent);
70473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,PNG_LIBPNG_VER_STRING,MaxTextExtent);
704847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(PNG_LIBPNG_VER_STRING,png_get_header_ver(NULL)) != 0)
70503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
70513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
70523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,png_get_libpng_ver(NULL),
70533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            MaxTextExtent);
70543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
70553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
705647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("MNG");
70583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->seekable_stream=MagickTrue;  /* To do: eliminate this. */
705947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
70613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadMNGImage;
70623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteMNGImage;
70633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
706447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsMNG;
70663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Multiple-image Network Graphics");
706747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
70693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
707047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
70723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(MNGNote);
70733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
70743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG");
707647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
70783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
70793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
70803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
708147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
70833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
70843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Portable Network Graphics");
70853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
708647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
70883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
708947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(PNGNote);
70913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
70923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
70933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG8");
709447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
70953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
70963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
70973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
70983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
709947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString(
71033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "8-bit indexed with optional binary transparency");
71043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG24");
71083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *version='\0';
710947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ZLIB_VERSION)
71113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,"zlib ",MaxTextExtent);
71123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ConcatenateMagickString(version,ZLIB_VERSION,MaxTextExtent);
711347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(ZLIB_VERSION,zlib_version) != 0)
71153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
71163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,",",MaxTextExtent);
71173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) ConcatenateMagickString(version,zlib_version,MaxTextExtent);
71183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
71193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
712047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*version != '\0')
71223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    entry->version=ConstantString(version);
712347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
712847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque 24-bit RGB");
71323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PNG32");
713647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPNGImage;
71393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePNGImage;
71403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
714147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPNG;
71433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("opaque or transparent 32-bit RGBA");
71453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
71473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("JNG");
714947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
71513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
71523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadJNGImage;
71533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteJNGImage;
71543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
71553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
715647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsJNG;
71583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->adjoin=MagickFalse;
71593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("JPEG Network Graphics");
71603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PNG");
71613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->note=ConstantString(JNGNote);
71623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
716347b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
716418b17443128598500357da7bff2f01683cf32890cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7165cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_semaphore=AllocateSemaphoreInfo();
716618b17443128598500357da7bff2f01683cf32890cristy#endif
716747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
71693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
71703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
71713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
71723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P N G I m a g e                                       %
71773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
71803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPNGImage() removes format registrations made by the
71833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG module from the list of supported formats.
71843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPNGImage method is:
71863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPNGImage(void)
71883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
71893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
71903ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPNGImage(void)
71913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
71923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("MNG");
71933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG");
71943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG8");
71953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG24");
71963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PNG32");
71973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("JNG");
719847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
71993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7200cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_semaphore != (SemaphoreInfo *) NULL)
7201cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    DestroySemaphoreInfo(&ping_semaphore);
72023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
72033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
72043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_PNG_DELEGATE)
720625c1e2baba76d9cf3ec582f217f96af95259e747glennrp#if PNG_LIBPNG_VER > 10011
72073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
72083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e M N G I m a g e                                                 %
72133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
72163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteMNGImage() writes an image in the Portable Network Graphics
72193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Group's "Multiple-image Network Graphics" encoded image format.
72203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
72223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteMNGImage method is:
72243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72251e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WriteMNGImage(const ImageInfo *image_info,
72261e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
72273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
72293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
72313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
72333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72341e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
72353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  To do (as of version 5.5.2, November 26, 2002 -- glennrp -- see also
72373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    "To do" under ReadPNGImage):
72383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Preserve all unknown and not-yet-handled known chunks found in input
72403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    PNG file and copy them  into output PNG files according to the PNG
72413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    copying rules.
72423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Write the iCCP chunk at MNG level when (icc profile length > 0)
72443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Improve selection of color type (use indexed-colour or indexed-colour
72463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    with tRNS when 256 or fewer unique RGBA values are present).
72473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Figure out what to do with "dispose=<restore-to-previous>" (dispose == 3)
72493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    This will be complicated if we limit ourselves to generating MNG-LC
72503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    files.  For now we ignore disposal method 3 and simply overlay the next
72513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    image on it.
72523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical PLTE's or PLTE/tRNS combinations and use a
72543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    global MNG PLTE or PLTE/tRNS combination when appropriate.
72553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    [mostly done 15 June 1999 but still need to take care of tRNS]
72563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sRGB and replace with a global sRGB (and remove
72583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    gAMA/cHRM if sRGB is found; check for identical gAMA/cHRM and
72593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    replace with global gAMA/cHRM (or with sRGB if appropriate; replace
72603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    local gAMA/cHRM with local sRGB if appropriate).
72613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Check for identical sBIT chunks and write global ones.
72633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide option to skip writing the signature tEXt chunks.
72653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use signatures to detect identical objects and reuse the first
72673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instance of such objects instead of writing duplicate objects.
72683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Use a smaller-than-32k value of compression window size when
72703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    appropriate.
72713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Encode JNG datastreams.  Mostly done as of 5.5.2; need to write
72733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    ancillary text chunks and save profiles.
72743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force LC files (to ensure exact framing rate)
72763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    instead of VLC.
72773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
72783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    Provide an option to force VLC files instead of LC, even when offsets
72793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    are present.  This will involve expanding the embedded images with a
72803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    transparent region at the top and/or left.
72813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
72823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72833ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void
7284cf002022280cc4dedb2748ad6f415aac1d44f530glennrpMagick_png_write_raw_profile(const ImageInfo *image_info,png_struct *ping,
72853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_info *ping_info, unsigned char *profile_type, unsigned char
72863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *profile_description, unsigned char *profile_data, png_uint_32 length)
72873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
72883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_textp
72893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text;
72903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7291bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   register ssize_t
72923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     i;
72933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
72953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *sp;
72963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_charp
72983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     dp;
72993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_uint_32
73013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length,
73023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     description_length;
73033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   unsigned char
73053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
73063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (LocaleNCompare((char *) profile_type+1, "ng-chunk-",9) == 0)
73083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return;
73093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->verbose)
73113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
73120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp       (void) printf("writing raw profile: type=%s, length=%.20g\n",
73130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (char *) profile_type, (double) length);
73143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
73150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
73163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
73173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   description_length=(png_uint_32) strlen((const char *) profile_description);
73183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   allocated_length=(png_uint_32) (length*2 + (length >> 5) + 20
73193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      + description_length);
73203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text=(png_charp) png_malloc(ping,allocated_length);
73213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key=(png_charp) png_malloc(ping, (png_uint_32) 80);
73223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].key[0]='\0';
73233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,
73243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "Raw profile type ",MaxTextExtent);
73253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) ConcatenateMagickString(text[0].key,(const char *) profile_type,62);
73263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   sp=profile_data;
73273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp=text[0].text;
73283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
73293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   (void) CopyMagickString(dp,(const char *) profile_description,
73303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     allocated_length);
73313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=description_length;
73323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
73333b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy   (void) FormatLocaleString(dp,allocated_length-
7334f2faecf9facdbbb14fcba373365f9f691a9658e0cristy     (png_size_t) (dp-text[0].text),"%8lu ",(unsigned long) length);
73353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   dp+=8;
733647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7337bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy   for (i=0; i < (ssize_t) length; i++)
73383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   {
73393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (i%36 == 0)
73403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       *dp++='\n';
73413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp >> 4) & 0x0f)];
73423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     *(dp++)=(char) hex[((*sp++ ) & 0x0f)];
73433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
734447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp++='\n';
73463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *dp='\0';
73473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].text_length=(png_size_t) (dp-text[0].text);
73483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   text[0].compression=image_info->compression == NoCompression ||
73493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (image_info->compression == UndefinedCompression &&
73503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     text[0].text_length < 128) ? -1 : 0;
735147b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (text[0].text_length <= allocated_length)
73533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_set_text(ping,ping_info,text,1);
735447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].text);
73563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text[0].key);
73573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   png_free(ping,text);
73583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
73593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7360cf002022280cc4dedb2748ad6f415aac1d44f530glennrpstatic MagickBooleanType Magick_png_write_chunk_from_profile(Image *image,
73614383ec8c3c8811128f5a8a034d67c47db5e7e75acristy  const char *string, MagickBooleanType logging)
73623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
73633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
73643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name;
73653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
73673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
73683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
73703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *data;
73713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_uint_32 length;
73733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
73743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetImageProfileIterator(image);
737547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
737647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  for (name=GetNextImageProfile(image); name != (const char *) NULL; )
737747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp  {
73783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    profile=GetImageProfile(image,name);
737947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
73803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (profile != (const StringInfo *) NULL)
73813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
73823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StringInfo
7383cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          *ping_profile;
73843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
738547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp        if (LocaleNCompare(name,string,11) == 0)
738647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          {
738747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            if (logging != MagickFalse)
738847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
738947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp                   "  Found %s profile",name);
739047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
7391cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=CloneStringInfo(profile);
7392cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            data=GetStringInfoDatum(ping_profile),
7393cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            length=(png_uint_32) GetStringInfoLength(ping_profile);
739447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[4]=data[3];
739547b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[3]=data[2];
739647b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[2]=data[1];
739747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            data[1]=data[0];
739847b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,length-5);  /* data length */
739947b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlob(image,length-1,data+1);
740047b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp            (void) WriteBlobMSBULong(image,crc32(0,data+1,(uInt) length-1));
7401cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            ping_profile=DestroyStringInfo(ping_profile);
740247b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp          }
74033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
740447b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      name=GetNextImageProfile(image);
74063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   }
740747b9dd5e18d5870d82f2a28c6160b32917916ad7glennrp
74083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return(MagickTrue);
74093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
74103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7411b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7412b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp/* Write one PNG image */
74133ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
7414b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp   const ImageInfo *IMimage_info,Image *IMimage)
74153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7416b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  Image
7417b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image;
7418b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
7419b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  ImageInfo
7420b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp    *image_info;
7421b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
74223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
74233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    s[2];
74243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
74263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *name,
74273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *property,
74283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
74293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const StringInfo
74313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *profile;
74323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
74343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    num_passes,
7435cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp    pass;
7436cecd5765c41f64cc68d4a5d77bb4afe92707a49eglennrp
7437e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp  png_byte
7438e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp     ping_trans_alpha[256];
74395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
744039992b4dd9b12ef752d55b8e402c069698851f72glennrp  png_color
744139992b4dd9b12ef752d55b8e402c069698851f72glennrp     palette[257];
74423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74435af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_color_16
74445af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_background,
74455af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_trans_color;
74465af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
74473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_info
74483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping_info;
74493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_struct
74513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *ping;
74523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_uint_32
74545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_height,
74555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_width;
74565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
74583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y;
74593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
746158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    image_matte,
746221f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
746358e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp    matte,
746458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp
7465da8f3a7bfddac2680a3069a490db541e7944edafglennrp    ping_have_blob,
7466fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency,
7467d6bf1617e99df0272b231855a933a74e99b6578fglennrp    ping_have_color,
74688d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp    ping_have_non_bw,
746939992b4dd9b12ef752d55b8e402c069698851f72glennrp    ping_have_PLTE,
7470991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_bKGD,
7471991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_pHYs,
7472991d11dd9c33e65872778b81aff1347cd2878154glennrp    ping_have_tRNS,
747326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
747426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_bKGD,
747526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_cHRM,
7476a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    ping_exclude_date,
7477e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_EXIF, */
747826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_gAMA,
747926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_iCCP,
748026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    /* ping_exclude_iTXt, */
748126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_oFFs,
748226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_pHYs,
748326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_sRGB,
748426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_tEXt,
7485e4e2d7916fb10ae2957bc36639b56fa303fd4a0eglennrp    /* ping_exclude_tRNS, */
748626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_vpAg,
748726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zCCP, /* hex-encoded iCCP */
748826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ping_exclude_zTXt,
748926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
74908d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp    ping_preserve_colormap,
74910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    ping_need_colortype_warning,
74920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
749382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    status,
74948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    tried_332,
7495d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_333,
7496d337164012450d70d62e71cf4a308a29004f7d57glennrp    tried_444;
74973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
74983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
74993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
75003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7501bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
75023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
75033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
75043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7506cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    *ping_pixels;
75073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75085af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  volatile int
7509f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    image_colors,
75100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    ping_bit_depth,
75115af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_color_type,
75125af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_interlace_method,
75135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_compression_method,
75145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_filter_method,
75155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    ping_num_trans;
75165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7517bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
75185af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    image_depth,
75195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    old_bit_depth;
75203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7521bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
75223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quality,
75233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    rowbytes,
75243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    save_image_depth;
75253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7526dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  int
7527fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    j,
7528f09bdedccf9ca10bc002a946227df3367cb58d14glennrp    number_colors,
75298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_opaque,
75308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_semitransparent,
75318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    number_transparent,
7532dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_unit_type;
7533dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7534dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  png_uint_32
7535dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_x_resolution,
7536dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    ping_pHYs_y_resolution;
7537dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
75383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
7539fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOnePNGImage()");
75403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7541b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image = CloneImage(IMimage,0,0,MagickFalse,&IMimage->exception);
7542b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=(ImageInfo *) CloneImageInfo(IMimage_info);
75438d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (image_info == (ImageInfo *) NULL)
75447b2cc79f1f54b48a9c3fe4eb3afbc2ebd6f6ec08glennrp     ThrowWriterException(ResourceLimitError, "MemoryAllocationFailed");
7545b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
75463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
7547cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  LockSemaphoreInfo(ping_semaphore);
75483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
75493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
75505af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  /* Initialize some stuff */
75510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_bit_depth=0,
75525af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_color_type=0,
75535af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=0,
75545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_compression_method=0,
75555af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_filter_method=0,
75565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_num_trans = 0;
75575af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.red = 0;
75595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.green = 0;
75605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.blue = 0;
75615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.gray = 0;
75625af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_background.index = 0;
75635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
75645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.red=0;
75655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.green=0;
75665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.blue=0;
75675af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_trans_color.gray=0;
75685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
7569dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_unit_type = 0;
7570dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_x_resolution = 0;
7571dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp  ping_pHYs_y_resolution = 0;
7572dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
7573da8f3a7bfddac2680a3069a490db541e7944edafglennrp  ping_have_blob=MagickFalse;
7574d6bf1617e99df0272b231855a933a74e99b6578fglennrp  ping_have_color=MagickTrue;
75758d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp  ping_have_non_bw=MagickTrue;
757639992b4dd9b12ef752d55b8e402c069698851f72glennrp  ping_have_PLTE=MagickFalse;
7577991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_bKGD=MagickFalse;
7578991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_pHYs=MagickFalse;
7579991d11dd9c33e65872778b81aff1347cd2878154glennrp  ping_have_tRNS=MagickFalse;
7580991d11dd9c33e65872778b81aff1347cd2878154glennrp
75810e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_bKGD=mng_info->ping_exclude_bKGD;
75820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_cHRM=mng_info->ping_exclude_cHRM;
7583a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  ping_exclude_date=mng_info->ping_exclude_date;
7584dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_EXIF=mng_info->ping_exclude_EXIF; */
75850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_gAMA=mng_info->ping_exclude_gAMA;
75860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_iCCP=mng_info->ping_exclude_iCCP;
75870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* ping_exclude_iTXt=mng_info->ping_exclude_iTXt; */
75880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_oFFs=mng_info->ping_exclude_oFFs;
75890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_pHYs=mng_info->ping_exclude_pHYs;
75900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_sRGB=mng_info->ping_exclude_sRGB;
75910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_tEXt=mng_info->ping_exclude_tEXt;
7592dde35db6e37a8fd3adaa19bdfe20c7a54b2085efglennrp  /* ping_exclude_tRNS=mng_info->ping_exclude_tRNS; */
75930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_vpAg=mng_info->ping_exclude_vpAg;
75940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zCCP=mng_info->ping_exclude_zCCP; /* hex-encoded iCCP in zTXt */
75950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_exclude_zTXt=mng_info->ping_exclude_zTXt;
75960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
75978d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  ping_preserve_colormap = mng_info->ping_preserve_colormap;
75980e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  ping_need_colortype_warning = MagickFalse;
75990e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
76008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_opaque = 0;
76018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_semitransparent = 0;
76028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  number_transparent = 0;
76038bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7604fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  if (logging != MagickFalse)
7605fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
7606fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == UndefinedClass)
7607fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7608fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=UndefinedClass");
7609fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == DirectClass)
7610fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7611fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=DirectClass");
7612fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      if (image->storage_class == PseudoClass)
7613fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7614fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp          "    storage_class=PseudoClass");
7615fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    }
761628af3713c9111a471cc868c787760de89236fa3cglennrp
76177e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  if (image->storage_class == PseudoClass &&
76187e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32 ||
76197e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     (mng_info->write_png_colortype != 0 &&
76207e65e93c71716f2a5c03c0808adedae21d519fb2glennrp     mng_info->write_png_colortype != 4)))
76217e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    {
76227e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      (void) SyncImage(image);
76237e65e93c71716f2a5c03c0808adedae21d519fb2glennrp      image->storage_class = DirectClass;
76247e65e93c71716f2a5c03c0808adedae21d519fb2glennrp    }
76257e65e93c71716f2a5c03c0808adedae21d519fb2glennrp
7626c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp  if (ping_preserve_colormap == MagickFalse)
762728af3713c9111a471cc868c787760de89236fa3cglennrp    {
7628c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      if (image->storage_class != PseudoClass && image->colormap != NULL)
7629c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
7630c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          /* Free the bogus colormap; it can cause trouble later */
7631c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           if (logging != MagickFalse)
7632c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7633c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              "    Freeing bogus colormap");
7634c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (void *) RelinquishMagickMemory(image->colormap);
7635c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           image->colormap=NULL;
7636c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        }
763728af3713c9111a471cc868c787760de89236fa3cglennrp    }
7638bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
7639510d06a3f7063e91993e13d546d5685048248074cristy  if (IsRGBColorspace(image->colorspace) == MagickFalse)
76403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
76410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
76423241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  /*
76433241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    Sometimes we get PseudoClass images whose RGB values don't match
76443241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp    the colors in the colormap.  This code syncs the RGB values.
76453241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  */
76463241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp  if (image->depth <= 8 && image->taint && image->storage_class == PseudoClass)
76473241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp     (void) SyncImage(image);
76483241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
7649a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#if (MAGICKCORE_QUANTUM_DEPTH == 8)
7650a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp  if (image->depth > 8)
7651a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    {
7652a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      if (logging != MagickFalse)
7653a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7654a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp          "    Reducing PNG bit depth to 8 since this is a Q8 build.");
7655a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
7656a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp      image->depth=8;
7657a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp    }
7658a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp#endif
7659a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
76608e58efdecda887b08ef730d68290a61081ef2566glennrp  /* Respect the -depth option */
766167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < MAGICKCORE_QUANTUM_DEPTH)
766267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp    {
76634c08aed51c5899665ade97263692328eea4af106cristy       register Quantum
76648e58efdecda887b08ef730d68290a61081ef2566glennrp         *r;
76658e58efdecda887b08ef730d68290a61081ef2566glennrp
76668e58efdecda887b08ef730d68290a61081ef2566glennrp       ExceptionInfo
76678e58efdecda887b08ef730d68290a61081ef2566glennrp         *exception;
76688e58efdecda887b08ef730d68290a61081ef2566glennrp
76698e58efdecda887b08ef730d68290a61081ef2566glennrp       exception=(&image->exception);
76708e58efdecda887b08ef730d68290a61081ef2566glennrp
76718e58efdecda887b08ef730d68290a61081ef2566glennrp       if (image->depth > 8)
76728e58efdecda887b08ef730d68290a61081ef2566glennrp         {
76738e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 16
76748e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 16-bit */
767591d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR16PacketRGBO(image->background_color);
76768e58efdecda887b08ef730d68290a61081ef2566glennrp
76778e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
76788e58efdecda887b08ef730d68290a61081ef2566glennrp           {
76798e58efdecda887b08ef730d68290a61081ef2566glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
76808e58efdecda887b08ef730d68290a61081ef2566glennrp                 exception);
76818e58efdecda887b08ef730d68290a61081ef2566glennrp
76824c08aed51c5899665ade97263692328eea4af106cristy             if (r == (Quantum *) NULL)
76838e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
76848e58efdecda887b08ef730d68290a61081ef2566glennrp
76858e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
76868e58efdecda887b08ef730d68290a61081ef2566glennrp             {
768754cf79782d2eba6612b706093f62474beb855c8dglennrp                LBR16PixelRGBA(r);
76888e58efdecda887b08ef730d68290a61081ef2566glennrp                r++;
76898e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7690bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
76918e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
76928e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
76938e58efdecda887b08ef730d68290a61081ef2566glennrp           }
76948e58efdecda887b08ef730d68290a61081ef2566glennrp
76958e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
76968e58efdecda887b08ef730d68290a61081ef2566glennrp           {
76973e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
76988e58efdecda887b08ef730d68290a61081ef2566glennrp             {
769991d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR16PacketRGBO(image->colormap[i]);
77008e58efdecda887b08ef730d68290a61081ef2566glennrp             }
77018e58efdecda887b08ef730d68290a61081ef2566glennrp           }
77028e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 16 */
77038e58efdecda887b08ef730d68290a61081ef2566glennrp         }
77048e58efdecda887b08ef730d68290a61081ef2566glennrp
77058e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 4)
77068e58efdecda887b08ef730d68290a61081ef2566glennrp         {
77078e58efdecda887b08ef730d68290a61081ef2566glennrp#if MAGICKCORE_QUANTUM_DEPTH > 8
77088e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 8-bit */
770991d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR08PacketRGBO(image->background_color);
77108e58efdecda887b08ef730d68290a61081ef2566glennrp
77118e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
77128e58efdecda887b08ef730d68290a61081ef2566glennrp           {
77138e58efdecda887b08ef730d68290a61081ef2566glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
77148e58efdecda887b08ef730d68290a61081ef2566glennrp                 exception);
77158e58efdecda887b08ef730d68290a61081ef2566glennrp
77164c08aed51c5899665ade97263692328eea4af106cristy             if (r == (Quantum *) NULL)
77178e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
77188e58efdecda887b08ef730d68290a61081ef2566glennrp
77198e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
77208e58efdecda887b08ef730d68290a61081ef2566glennrp             {
772154cf79782d2eba6612b706093f62474beb855c8dglennrp                LBR08PixelRGBA(r);
77228e58efdecda887b08ef730d68290a61081ef2566glennrp                r++;
77238e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7724bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
77258e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
77268e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
77278e58efdecda887b08ef730d68290a61081ef2566glennrp           }
77288e58efdecda887b08ef730d68290a61081ef2566glennrp
77298e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
77308e58efdecda887b08ef730d68290a61081ef2566glennrp           {
77313e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
77328e58efdecda887b08ef730d68290a61081ef2566glennrp             {
773391d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR08PacketRGBO(image->colormap[i]);
77348e58efdecda887b08ef730d68290a61081ef2566glennrp             }
77358e58efdecda887b08ef730d68290a61081ef2566glennrp           }
77368e58efdecda887b08ef730d68290a61081ef2566glennrp#endif /* MAGICKCORE_QUANTUM_DEPTH > 8 */
77378e58efdecda887b08ef730d68290a61081ef2566glennrp         }
77388e58efdecda887b08ef730d68290a61081ef2566glennrp       else
77398e58efdecda887b08ef730d68290a61081ef2566glennrp         if (image->depth > 2)
77408e58efdecda887b08ef730d68290a61081ef2566glennrp         {
77418e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 4-bit */
774291d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR04PacketRGBO(image->background_color);
77438e58efdecda887b08ef730d68290a61081ef2566glennrp
77448e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
77458e58efdecda887b08ef730d68290a61081ef2566glennrp           {
77468e58efdecda887b08ef730d68290a61081ef2566glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
77478e58efdecda887b08ef730d68290a61081ef2566glennrp                 exception);
77488e58efdecda887b08ef730d68290a61081ef2566glennrp
77494c08aed51c5899665ade97263692328eea4af106cristy             if (r == (Quantum *) NULL)
77508e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
77518e58efdecda887b08ef730d68290a61081ef2566glennrp
77528e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
77538e58efdecda887b08ef730d68290a61081ef2566glennrp             {
775454cf79782d2eba6612b706093f62474beb855c8dglennrp                LBR04PixelRGBA(r);
77558e58efdecda887b08ef730d68290a61081ef2566glennrp                r++;
77568e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7757bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
77588e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
77598e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
77608e58efdecda887b08ef730d68290a61081ef2566glennrp           }
77618e58efdecda887b08ef730d68290a61081ef2566glennrp
77628e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
77638e58efdecda887b08ef730d68290a61081ef2566glennrp           {
77643e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
77658e58efdecda887b08ef730d68290a61081ef2566glennrp             {
776691d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR04PacketRGBO(image->colormap[i]);
77678e58efdecda887b08ef730d68290a61081ef2566glennrp             }
77688e58efdecda887b08ef730d68290a61081ef2566glennrp           }
77698e58efdecda887b08ef730d68290a61081ef2566glennrp         }
77708e58efdecda887b08ef730d68290a61081ef2566glennrp
77718e58efdecda887b08ef730d68290a61081ef2566glennrp       else if (image->depth > 1)
77728e58efdecda887b08ef730d68290a61081ef2566glennrp         {
77738e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 2-bit */
777491d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR02PacketRGBO(image->background_color);
77758e58efdecda887b08ef730d68290a61081ef2566glennrp
77768e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
77778e58efdecda887b08ef730d68290a61081ef2566glennrp           {
77788e58efdecda887b08ef730d68290a61081ef2566glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
77798e58efdecda887b08ef730d68290a61081ef2566glennrp                 exception);
77808e58efdecda887b08ef730d68290a61081ef2566glennrp
77814c08aed51c5899665ade97263692328eea4af106cristy             if (r == (Quantum *) NULL)
77828e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
77838e58efdecda887b08ef730d68290a61081ef2566glennrp
77848e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
77858e58efdecda887b08ef730d68290a61081ef2566glennrp             {
778654cf79782d2eba6612b706093f62474beb855c8dglennrp                LBR02PixelRGBA(r);
77878e58efdecda887b08ef730d68290a61081ef2566glennrp                r++;
77888e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7789bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
77908e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
77918e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
77928e58efdecda887b08ef730d68290a61081ef2566glennrp           }
77938e58efdecda887b08ef730d68290a61081ef2566glennrp
77948e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
77958e58efdecda887b08ef730d68290a61081ef2566glennrp           {
77963e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
77978e58efdecda887b08ef730d68290a61081ef2566glennrp             {
779891d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR02PacketRGBO(image->colormap[i]);
77998e58efdecda887b08ef730d68290a61081ef2566glennrp             }
78008e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78018e58efdecda887b08ef730d68290a61081ef2566glennrp         }
78028e58efdecda887b08ef730d68290a61081ef2566glennrp       else
78038e58efdecda887b08ef730d68290a61081ef2566glennrp         {
78048e58efdecda887b08ef730d68290a61081ef2566glennrp           /* Scale to 1-bit */
780591d99255dd77083750426ba5463e002a586bc9a6glennrp           LBR01PacketRGBO(image->background_color);
78068e58efdecda887b08ef730d68290a61081ef2566glennrp
78078e58efdecda887b08ef730d68290a61081ef2566glennrp           for (y=0; y < (ssize_t) image->rows; y++)
78088e58efdecda887b08ef730d68290a61081ef2566glennrp           {
78098e58efdecda887b08ef730d68290a61081ef2566glennrp             r=GetAuthenticPixels(image,0,y,image->columns,1,
78108e58efdecda887b08ef730d68290a61081ef2566glennrp                 exception);
78118e58efdecda887b08ef730d68290a61081ef2566glennrp
78124c08aed51c5899665ade97263692328eea4af106cristy             if (r == (Quantum *) NULL)
78138e58efdecda887b08ef730d68290a61081ef2566glennrp               break;
78148e58efdecda887b08ef730d68290a61081ef2566glennrp
78158e58efdecda887b08ef730d68290a61081ef2566glennrp             for (x=0; x < (ssize_t) image->columns; x++)
78168e58efdecda887b08ef730d68290a61081ef2566glennrp             {
781754cf79782d2eba6612b706093f62474beb855c8dglennrp                LBR01PixelRGBA(r);
78188e58efdecda887b08ef730d68290a61081ef2566glennrp                r++;
78198e58efdecda887b08ef730d68290a61081ef2566glennrp             }
7820bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
78218e58efdecda887b08ef730d68290a61081ef2566glennrp             if (SyncAuthenticPixels(image,exception) == MagickFalse)
78228e58efdecda887b08ef730d68290a61081ef2566glennrp                break;
78238e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78248e58efdecda887b08ef730d68290a61081ef2566glennrp
78258e58efdecda887b08ef730d68290a61081ef2566glennrp           if (image->storage_class == PseudoClass && image->colormap != NULL)
78268e58efdecda887b08ef730d68290a61081ef2566glennrp           {
78273e08f1130848df134cab76223cc758607d25efa7cristy             for (i=0; i < (ssize_t) image->colors; i++)
78288e58efdecda887b08ef730d68290a61081ef2566glennrp             {
782991d99255dd77083750426ba5463e002a586bc9a6glennrp               LBR01PacketRGBO(image->colormap[i]);
78308e58efdecda887b08ef730d68290a61081ef2566glennrp             }
78318e58efdecda887b08ef730d68290a61081ef2566glennrp           }
78328e58efdecda887b08ef730d68290a61081ef2566glennrp         }
7833cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp    }
7834cc95c3f37f025a52b71d927cba8009c4f8bc83a5glennrp
783567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  /* To do: set to next higher multiple of 8 */
783667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp  if (image->depth < 8)
783770e68a844517efda3094dc170a8f54affc9c82bcglennrp     image->depth=8;
7838a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
78392b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 16)
78402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp  /* PNG does not handle depths greater than 16 so reduce it even
78412b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   * if lossy
78422b013e4b9b602533eff410e61c3683fb2a3ab913glennrp   */
78438e58efdecda887b08ef730d68290a61081ef2566glennrp  if (image->depth > 8)
78442b013e4b9b602533eff410e61c3683fb2a3ab913glennrp      image->depth=16;
78452b013e4b9b602533eff410e61c3683fb2a3ab913glennrp#endif
78462b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
78473faa9a3fb01696daaf976d595f492cb530bffb21glennrp#if (MAGICKCORE_QUANTUM_DEPTH > 8)
7848c722dd852e8abe407c2846d39662f7ade9c234deglennrp  if (image->depth == 16 && mng_info->write_png_depth != 16)
78498bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    if (mng_info->write_png8 || LosslessReduceDepthOK(image) != MagickFalse)
78508640fb5e9b1094f35f8beab436f81661b8a99448glennrp      image->depth = 8;
78518640fb5e9b1094f35f8beab436f81661b8a99448glennrp#endif
78528640fb5e9b1094f35f8beab436f81661b8a99448glennrp
7853c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp  /* Normally we run this just once, but in the case of writing PNG8
7854e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * we reduce the transparency to binary and run again, then if there
7855e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp   * are still too many colors we reduce to a simple 4-4-4-1, then 3-3-3-1
78568ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * RGBA palette and run again, and then to a simple 3-3-2-1 RGBA
78578ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * palette.  Then (To do) we take care of a final reduction that is only
78588ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * needed if there are still 256 colors present and one of them has both
78598ca51ad2da164dabc55b192ed7884b745fde0e26glennrp   * transparent and opaque instances.
7860c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   */
786182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
78628ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  tried_332 = MagickFalse;
786382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp  tried_333 = MagickFalse;
7864d337164012450d70d62e71cf4a308a29004f7d57glennrp  tried_444 = MagickFalse;
786582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
78668ca51ad2da164dabc55b192ed7884b745fde0e26glennrp  for (j=0; j<6; j++)
7867d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp  {
7868d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp    /* BUILD_PALETTE
7869d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7870d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get DirectClass images that have 256 colors or fewer.
7871d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will build a colormap.
7872d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7873d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also, sometimes we get PseudoClass images with an out-of-date
7874d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * colormap.  This code will replace the colormap with a new one.
7875d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Sometimes we get PseudoClass images that have more than 256 colors.
7876d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * This code will delete the colormap and change the image to
7877d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * DirectClass.
7878d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
78794c08aed51c5899665ade97263692328eea4af106cristy     * If image->matte is MagickFalse, we ignore the alpha channel
7880d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * even though it sometimes contains left-over non-opaque values.
7881d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7882d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Also we gather some information (number of opaque, transparent,
7883d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * and semitransparent pixels, and whether the image has any non-gray
7884d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * pixels or only black-and-white pixels) that we might need later.
7885d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *
7886d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * Even if the user wants to force GrayAlpha or RGBA (colortype 4 or 6)
7887d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     * we need to check for bogus non-opaque values, at least.
7888d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     */
78893c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7890d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   ExceptionInfo
7891d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     *exception;
78928bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7893d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   int
7894d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     n;
78958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
7896d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   PixelPacket
7897d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     opaque[260],
7898d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     semitransparent[260],
7899d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     transparent[260];
79008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
79014c08aed51c5899665ade97263692328eea4af106cristy   register const Quantum
79024c08aed51c5899665ade97263692328eea4af106cristy     *s;
7903d6bf1617e99df0272b231855a933a74e99b6578fglennrp
79044c08aed51c5899665ade97263692328eea4af106cristy   register Quantum
79054c08aed51c5899665ade97263692328eea4af106cristy     *q,
7906fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     *r;
7907fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
7908d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7909d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7910d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         "    Enter BUILD_PALETTE:");
7911d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7912d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp   if (logging != MagickFalse)
7913d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7914d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7915d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->columns=%.20g",(double) image->columns);
7916d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7917d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->rows=%.20g",(double) image->rows);
7918d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7919d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->matte=%.20g",(double) image->matte);
792003812ae402fb53d548f0e1d7d14720768f803c2dglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7921d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      image->depth=%.20g",(double) image->depth);
79223c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
7923fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (image->storage_class == PseudoClass && image->colormap != NULL)
79247ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp       {
79257ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7926d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             "      Original colormap:");
79278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79284c08aed51c5899665ade97263692328eea4af106cristy             "        i    (red,green,blue,alpha)");
79292cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7930d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i < 256; i++)
79317ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         {
7932d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7933d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7934d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7935d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7936d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7937d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
79384c08aed51c5899665ade97263692328eea4af106cristy                    (int) image->colormap[i].alpha);
79397ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp         }
79402cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7941d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=image->colors - 10; i < (ssize_t) image->colors; i++)
7942d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
7943d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (i > 255)
7944d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
7945d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7946d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "        %d    (%d,%d,%d,%d)",
7947d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) i,
7948d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].red,
7949d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].green,
7950d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    (int) image->colormap[i].blue,
79514c08aed51c5899665ade97263692328eea4af106cristy                    (int) image->colormap[i].alpha);
7952d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
7953d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         }
7954d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
79552cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7956d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7957d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "      image->colors=%d",(int) image->colors);
795883c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
7959d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       if (image->colors == 0)
7960d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7961d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           "        (zero means unknown)");
79627ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
79638d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       if (ping_preserve_colormap == MagickFalse)
79648d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
79658d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp              "      Regenerate the colormap");
7966d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
79677ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7968d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     exception=(&image->exception);
7969d6bf1617e99df0272b231855a933a74e99b6578fglennrp
7970d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=0;
7971fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_opaque = 0;
7972fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_semitransparent = 0;
7973fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     number_transparent = 0;
79742cc891a179d622dde7bbb8854138851e828bc6eaglennrp
7975d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     for (y=0; y < (ssize_t) image->rows; y++)
7976d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     {
7977d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
79787ddcc22478e0199aa11e9aeab088874b3b2cef63glennrp
7979acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy       if (q == (Quantum *) NULL)
7980d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         break;
798197fd3d052fbd2e629d5d2387f26de9e250dd3e32glennrp
7982d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       for (x=0; x < (ssize_t) image->columns; x++)
7983d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
79844737d521d1d9e5d9a7c55375027ba4befc711046glennrp           if (image->matte == MagickFalse ||
79854c08aed51c5899665ade97263692328eea4af106cristy              GetPixelAlpha(image,q) == OpaqueAlpha)
79868d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
7987d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_opaque < 259)
79888d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
7989d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_opaque == 0)
7990d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
79914c08aed51c5899665ade97263692328eea4af106cristy                       GetPixelPacket(image, q, opaque);
79924c08aed51c5899665ade97263692328eea4af106cristy                       opaque[0].alpha=OpaqueAlpha;
7993d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque=1;
7994d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
7995d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
7996d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_opaque; i++)
7997d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
79984c08aed51c5899665ade97263692328eea4af106cristy                       if (IsPixelEquivalent(image,q, opaque+i))
7999d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8000d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8001d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8002d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_opaque &&
8003d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque < 259)
8004d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8005d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_opaque++;
80064c08aed51c5899665ade97263692328eea4af106cristy                       GetPixelPacket(image, q, opaque+i);
80074c08aed51c5899665ade97263692328eea4af106cristy                       opaque[i].alpha=OpaqueAlpha;
8008d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
80098d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
80108d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
80114c08aed51c5899665ade97263692328eea4af106cristy           else if (GetPixelAlpha(image,q) == TransparentAlpha)
80128d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             {
8013d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_transparent < 259)
80148d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 {
8015d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_transparent == 0)
8016d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
80174c08aed51c5899665ade97263692328eea4af106cristy                       GetPixelPacket(image, q, transparent);
80184c08aed51c5899665ade97263692328eea4af106cristy                       ping_trans_color.red=(unsigned short)
80194c08aed51c5899665ade97263692328eea4af106cristy                         GetPixelRed(image,q);
80204c08aed51c5899665ade97263692328eea4af106cristy                       ping_trans_color.green=(unsigned short)
80214c08aed51c5899665ade97263692328eea4af106cristy                         GetPixelGreen(image,q);
80224c08aed51c5899665ade97263692328eea4af106cristy                       ping_trans_color.blue=(unsigned short)
80234c08aed51c5899665ade97263692328eea4af106cristy                         GetPixelBlue(image,q);
80244c08aed51c5899665ade97263692328eea4af106cristy                       ping_trans_color.gray=(unsigned short)
80254c08aed51c5899665ade97263692328eea4af106cristy                         GetPixelRed(image,q);
8026d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent = 1;
8027d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8028d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8029d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_transparent; i++)
8030d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
80314c08aed51c5899665ade97263692328eea4af106cristy                       if (IsPixelEquivalent(image,q, transparent+i))
8032d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8033d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8034d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8035d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_transparent &&
8036d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent < 259)
8037d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8038d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_transparent++;
80394c08aed51c5899665ade97263692328eea4af106cristy                       GetPixelPacket(image,q,transparent+i);
8040d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
80418d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp                 }
80428d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             }
8043d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8044d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8045d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (number_semitransparent < 259)
8046d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8047d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (number_semitransparent == 0)
8048d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
80494c08aed51c5899665ade97263692328eea4af106cristy                       GetPixelPacket(image,q,semitransparent);
8050d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent = 1;
8051d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
80528d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
8053d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (i=0; i< (ssize_t) number_semitransparent; i++)
8054d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
80554c08aed51c5899665ade97263692328eea4af106cristy                       if (IsPixelEquivalent(image,q, semitransparent+i)
80564c08aed51c5899665ade97263692328eea4af106cristy                           && GetPixelAlpha(image,q) ==
80574c08aed51c5899665ade97263692328eea4af106cristy                           semitransparent[i].alpha)
8058d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         break;
8059d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8060d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8061d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   if (i ==  (ssize_t) number_semitransparent &&
8062d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent < 259)
8063d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     {
8064d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       number_semitransparent++;
80654c08aed51c5899665ade97263692328eea4af106cristy                       GetPixelPacket(image, q, semitransparent+i);
8066d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     }
8067d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
80688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             }
8069ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy           q+=GetPixelChannels(image);
8070d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        }
8071d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     }
80723c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
80734054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     if (mng_info->write_png8 == MagickFalse &&
80744054bfbdca478fe065f01d7f8285f7c173ccfcfccristy         ping_exclude_bKGD == MagickFalse)
8075d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8076d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* Add the background color to the palette, if it
8077d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * isn't already there.
8078d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8079c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging != MagickFalse)
8080c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
8081c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8082c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  "      Check colormap for background (%d,%d,%d)",
8083c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.red,
8084c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.green,
8085c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                  (int) image->background_color.blue);
8086c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
8087d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          for (i=0; i<number_opaque; i++)
8088d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8089ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp             if (opaque[i].red == image->background_color.red &&
8090ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].green == image->background_color.green &&
8091ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp                 opaque[i].blue == image->background_color.blue)
8092ca7ad3a4c4d394b32265e215c857b485fb57296fglennrp               break;
8093d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8094d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (number_opaque < 259 && i == number_opaque)
809503812ae402fb53d548f0e1d7d14720768f803c2dglennrp            {
80968e045c8f9e00ec89df5b20bf07c059d60e7aaa77glennrp               opaque[i] = image->background_color;
8097c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               ping_background.index = i;
8098c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp               if (logging != MagickFalse)
8099c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 {
8100c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8101c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                       "      background_color index is %d",(int) i);
8102c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 }
8103c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
810403812ae402fb53d548f0e1d7d14720768f803c2dglennrp            }
8105a080bc32a4a8b2ffec83fd836a28753959175363glennrp          else if (logging != MagickFalse)
8106a080bc32a4a8b2ffec83fd836a28753959175363glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8107a080bc32a4a8b2ffec83fd836a28753959175363glennrp                  "      No room in the colormap to add background color");
8108d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
81092cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8110d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     image_colors=number_opaque+number_transparent+number_semitransparent;
81113241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8112a080bc32a4a8b2ffec83fd836a28753959175363glennrp     if (mng_info->write_png8 != MagickFalse && image_colors > 256)
8113a080bc32a4a8b2ffec83fd836a28753959175363glennrp       {
8114a080bc32a4a8b2ffec83fd836a28753959175363glennrp         /* No room for the background color; remove it. */
8115a080bc32a4a8b2ffec83fd836a28753959175363glennrp         number_opaque--;
8116a080bc32a4a8b2ffec83fd836a28753959175363glennrp         image_colors--;
8117a080bc32a4a8b2ffec83fd836a28753959175363glennrp       }
8118a080bc32a4a8b2ffec83fd836a28753959175363glennrp
8119d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8120d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8121d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image_colors > 256)
8122d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8123d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has more than 256 colors");
81243241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8125d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         else
8126d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8127d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      image has %d colors",image_colors);
8128d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
81293241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
81308d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     if (ping_preserve_colormap != MagickFalse)
81318d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       break;
81328d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
8133fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     if (mng_info->write_png_colortype != 7) /* We won't need this info */
8134d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8135d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_color=MagickFalse;
8136d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         ping_have_non_bw=MagickFalse;
81373241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8138d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if(image_colors > 256)
8139d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8140d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (y=0; y < (ssize_t) image->rows; y++)
8141d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8142d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
81436185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8144acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy               if (q == (Quantum *) NULL)
8145d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
81466185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8147e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               s=q;
8148e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               for (x=0; x < (ssize_t) image->columns; x++)
8149e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               {
8150e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 if (GetPixelRed(image,s) != GetPixelGreen(image,s) ||
8151e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                     GetPixelRed(image,s) != GetPixelBlue(image,s))
8152e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   {
8153e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_color=MagickTrue;
8154e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      ping_have_non_bw=MagickTrue;
8155e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                      break;
8156e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                   }
8157e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 s+=GetPixelChannels(image);
8158e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8159e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8160e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               if (ping_have_color != MagickFalse)
8161e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                 break;
8162e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp
8163d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               /* Worst case is black-and-white; we are looking at every
8164d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                * pixel twice.
8165d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                */
81666185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8167d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (ping_have_non_bw == MagickFalse)
8168d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8169d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   s=q;
8170d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   for (x=0; x < (ssize_t) image->columns; x++)
81716185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                   {
81724c08aed51c5899665ade97263692328eea4af106cristy                     if (GetPixelRed(image,s) != 0 &&
81734c08aed51c5899665ade97263692328eea4af106cristy                         GetPixelRed(image,s) != QuantumRange)
8174d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       {
8175d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                         ping_have_non_bw=MagickTrue;
8176e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp                         break;
8177d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       }
8178ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                     s+=GetPixelChannels(image);
8179d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   }
8180e5e6b80f72d72eb8dc5be1bd1425b4ad504f0ef7glennrp               }
8181d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8182bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp           }
8183bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp       }
81844f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
8185d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (image_colors < 257)
8186d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8187d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         PixelPacket
8188d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           colormap[260];
8189bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8190d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /*
8191d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * Initialize image colormap.
8192d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8193d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8194d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (logging != MagickFalse)
8195d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8196d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  "      Sort the new colormap");
8197d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8198d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        /* Sort palette, transparent first */;
8199d6bf1617e99df0272b231855a933a74e99b6578fglennrp
8200d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         n = 0;
82013241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8202d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_transparent; i++)
8203d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = transparent[i];
82043241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8205d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_semitransparent; i++)
8206d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = semitransparent[i];
8207d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8208d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<number_opaque; i++)
8209d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            colormap[n++] = opaque[i];
8210d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8211c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         ping_background.index +=
8212c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp           (number_transparent + number_semitransparent);
8213bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8214d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         /* image_colors < 257; search the colormap instead of the pixels
8215d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          * to get ping_have_color and ping_have_non_bw
8216d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          */
8217d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         for (i=0; i<n; i++)
8218d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         {
8219d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_color == MagickFalse)
8220d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8221d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (colormap[i].red != colormap[i].green ||
8222d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    colormap[i].red != colormap[i].blue)
8223d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  {
8224d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_color=MagickTrue;
8225d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     ping_have_non_bw=MagickTrue;
8226d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                     break;
8227d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  }
8228d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8229d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8230d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8231d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
8232d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               if (colormap[i].red != 0 && colormap[i].red != QuantumRange)
8233d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   ping_have_non_bw=MagickTrue;
8234d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             }
8235d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
82363241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp
8237d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp        if ((mng_info->ping_exclude_tRNS == MagickFalse ||
8238d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (number_transparent == 0 && number_semitransparent == 0)) &&
8239d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (((mng_info->write_png_colortype-1) ==
8240d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            PNG_COLOR_TYPE_PALETTE) ||
8241d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            (mng_info->write_png_colortype == 0)))
8242d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          {
8243d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
82446185c5395ac23a4c51586d671ec3e0ba9c126349glennrp              {
8245d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                if (n !=  (ssize_t) image_colors)
8246d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8247d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "   image_colors (%d) and n (%d)  don't match",
8248d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   image_colors, n);
82492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
8250d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8251d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      AcquireImageColormap");
8252d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8253d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8254d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            image->colors = image_colors;
8255d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8256d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (AcquireImageColormap(image,image_colors) ==
8257d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                MagickFalse)
82583faa9a3fb01696daaf976d595f492cb530bffb21glennrp               ThrowWriterException(ResourceLimitError,
82593faa9a3fb01696daaf976d595f492cb530bffb21glennrp                   "MemoryAllocationFailed");
8260d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8261d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (i=0; i< (ssize_t) image_colors; i++)
8262d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp               image->colormap[i] = colormap[i];
8263d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8264d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            if (logging != MagickFalse)
8265d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8266d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8267d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      image->colors=%d (%d)",
8268d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      (int) image->colors, image_colors);
8269bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8270d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8271d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                      "      Update the pixel indexes");
8272d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8273d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8274fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            /* Sync the pixel indices with the new colormap */
8275fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8276d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            for (y=0; y < (ssize_t) image->rows; y++)
8277d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            {
8278d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              q=GetAuthenticPixels(image,0,y,image->columns,1,
8279d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  exception);
82803c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8281acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy              if (q == (Quantum *) NULL)
8282d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                break;
82833c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8284bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8285d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              for (x=0; x < (ssize_t) image->columns; x++)
8286d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              {
8287d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                for (i=0; i< (ssize_t) image_colors; i++)
828803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                {
8289d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                  if ((image->matte == MagickFalse ||
82904c08aed51c5899665ade97263692328eea4af106cristy                      image->colormap[i].alpha == GetPixelAlpha(image,q)) &&
82914c08aed51c5899665ade97263692328eea4af106cristy                      image->colormap[i].red == GetPixelRed(image,q) &&
82924c08aed51c5899665ade97263692328eea4af106cristy                      image->colormap[i].green == GetPixelGreen(image,q) &&
82934c08aed51c5899665ade97263692328eea4af106cristy                      image->colormap[i].blue == GetPixelBlue(image,q))
82946185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  {
82954c08aed51c5899665ade97263692328eea4af106cristy                    SetPixelIndex(image,i,q);
8296d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    break;
82976185c5395ac23a4c51586d671ec3e0ba9c126349glennrp                  }
829803812ae402fb53d548f0e1d7d14720768f803c2dglennrp                }
8299ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                q+=GetPixelChannels(image);
8300d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              }
8301d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8302d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              if (SyncAuthenticPixels(image,exception) == MagickFalse)
8303d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 break;
8304d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            }
8305d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          }
8306d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
8307d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8308d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp     if (logging != MagickFalse)
8309d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       {
8310d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8311d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp            "      image->colors=%d", (int) image->colors);
8312d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8313d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp         if (image->colormap != NULL)
8314d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           {
8315d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
83164c08aed51c5899665ade97263692328eea4af106cristy                 "       i     (red,green,blue,alpha)");
831783c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
8318d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             for (i=0; i < (ssize_t) image->colors; i++)
8319d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             {
832072988485e53441bbc7e5e7fbcb8e81012212efb6cristy               if (i < 300 || i >= (ssize_t) image->colors - 10)
8321d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 {
8322d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8323d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                       "       %d     (%d,%d,%d,%d)",
8324d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) i,
8325d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].red,
8326d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].green,
8327d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                        (int) image->colormap[i].blue,
83284c08aed51c5899665ade97263692328eea4af106cristy                        (int) image->colormap[i].alpha);
8329d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                 }
83306185c5395ac23a4c51586d671ec3e0ba9c126349glennrp             }
83316185c5395ac23a4c51586d671ec3e0ba9c126349glennrp           }
83323c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8333d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_transparent < 257)
8334d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8335d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     = %d",
8336d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_transparent);
8337d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
83383c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8339d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8340d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_transparent     > 256");
83413c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8342d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_opaque < 257)
8343d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8344d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          = %d",
8345d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_opaque);
834603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
8347d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8348d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8349d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_opaque          > 256");
83506185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8351d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (number_semitransparent < 257)
8352d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8353d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent = %d",
8354d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   number_semitransparent);
83556185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
8356d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8357d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8358d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                   "      number_semitransparent > 256");
8359a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8360d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           if (ping_have_non_bw == MagickFalse)
8361d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8362d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are black or white");
8363a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
8364d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else if (ping_have_color == MagickFalse)
8365d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8366d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      All pixels and the background are gray");
8367d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp
8368d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp           else
8369d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8370d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp                    "      At least one pixel or the background is non-gray");
83716185c5395ac23a4c51586d671ec3e0ba9c126349glennrp
837203812ae402fb53d548f0e1d7d14720768f803c2dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
837303812ae402fb53d548f0e1d7d14720768f803c2dglennrp               "    Exit BUILD_PALETTE:");
8374d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp       }
83753c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
8376c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   if (mng_info->write_png8 == MagickFalse)
8377c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8378fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8379c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp   /* Make any reductions necessary for the PNG8 format */
8380c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    if (image_colors <= 256 &&
8381c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        image_colors != 0 && image->colormap != NULL &&
8382c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_semitransparent == 0 &&
8383c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        number_transparent <= 1)
8384c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      break;
8385fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8386c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have semitransparent colors so we threshold the
8387130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * opacity to 0 or OpaqueOpacity, and PNG8 can only have one
8388130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * transparent color so if more than one is transparent we merge
8389130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp     * them into image->background_color.
8390c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8391130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp    if (number_semitransparent != 0 || number_transparent > 1)
8392c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8393c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8394c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            "    Thresholding the alpha channel to binary");
8395fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8396c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        for (y=0; y < (ssize_t) image->rows; y++)
8397c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8398c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          r=GetAuthenticPixels(image,0,y,image->columns,1,
8399c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              exception);
8400fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
84014c08aed51c5899665ade97263692328eea4af106cristy          if (r == (Quantum *) NULL)
8402c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            break;
8403fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8404c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (x=0; x < (ssize_t) image->columns; x++)
8405c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
8406f73547f51486ebeea44ebe7236477424304ed320glennrp              if (GetPixelAlpha(image,r) < OpaqueAlpha/2)
84078ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                {
84084c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelPacket(image,&image->background_color,r);
84094c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,TransparentAlpha,r);
84108ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                }
84118ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              else
84124c08aed51c5899665ade97263692328eea4af106cristy                  SetPixelAlpha(image,OpaqueAlpha,r);
8413ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy              r+=GetPixelChannels(image);
8414c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8415bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8416c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
8417c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             break;
8418fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8419c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (image_colors != 0 && image_colors <= 256 &&
8420c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp             image->colormap != NULL)
8421c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (i=0; i<image_colors; i++)
84224c08aed51c5899665ade97263692328eea4af106cristy                image->colormap[i].alpha =
84234c08aed51c5899665ade97263692328eea4af106cristy                    (image->colormap[i].alpha > TransparentAlpha/2 ?
84244c08aed51c5899665ade97263692328eea4af106cristy                    TransparentAlpha : OpaqueAlpha);
8425c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8426c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8427c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8428c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8429c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    /* PNG8 can't have more than 256 colors so we quantize the pixels and
8430e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * background color to the 4-4-4-1, 3-3-3-1 or 3-3-2-1 palette.  If the
8431e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * image is mostly gray, the 4-4-4-1 palette is likely to end up with 256
8432e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp     * colors or less.
8433c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp     */
8434d337164012450d70d62e71cf4a308a29004f7d57glennrp    if (tried_444 == MagickFalse && (image_colors == 0 || image_colors > 256))
8435d337164012450d70d62e71cf4a308a29004f7d57glennrp      {
8436d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8437d337164012450d70d62e71cf4a308a29004f7d57glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8438d337164012450d70d62e71cf4a308a29004f7d57glennrp               "    Quantizing the background color to 4-4-4");
8439d337164012450d70d62e71cf4a308a29004f7d57glennrp
8440d337164012450d70d62e71cf4a308a29004f7d57glennrp        tried_444 = MagickTrue;
8441d337164012450d70d62e71cf4a308a29004f7d57glennrp
844291d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR04PacketRGB(image->background_color);
8443d337164012450d70d62e71cf4a308a29004f7d57glennrp
8444d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (logging != MagickFalse)
8445d337164012450d70d62e71cf4a308a29004f7d57glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8446d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the pixel colors to 4-4-4");
8447d337164012450d70d62e71cf4a308a29004f7d57glennrp
8448d337164012450d70d62e71cf4a308a29004f7d57glennrp        if (image->colormap == NULL)
8449d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8450d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (y=0; y < (ssize_t) image->rows; y++)
8451d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
8452d337164012450d70d62e71cf4a308a29004f7d57glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
8453d337164012450d70d62e71cf4a308a29004f7d57glennrp                exception);
8454d337164012450d70d62e71cf4a308a29004f7d57glennrp
84554c08aed51c5899665ade97263692328eea4af106cristy            if (r == (Quantum *) NULL)
8456d337164012450d70d62e71cf4a308a29004f7d57glennrp              break;
8457d337164012450d70d62e71cf4a308a29004f7d57glennrp
8458d337164012450d70d62e71cf4a308a29004f7d57glennrp            for (x=0; x < (ssize_t) image->columns; x++)
8459d337164012450d70d62e71cf4a308a29004f7d57glennrp            {
84604c08aed51c5899665ade97263692328eea4af106cristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
846154cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR04PixelRGB(r);
8462d337164012450d70d62e71cf4a308a29004f7d57glennrp              r++;
8463d337164012450d70d62e71cf4a308a29004f7d57glennrp            }
8464bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8465d337164012450d70d62e71cf4a308a29004f7d57glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8466d337164012450d70d62e71cf4a308a29004f7d57glennrp               break;
8467d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8468d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8469d337164012450d70d62e71cf4a308a29004f7d57glennrp
8470d337164012450d70d62e71cf4a308a29004f7d57glennrp        else /* Should not reach this; colormap already exists and
8471d337164012450d70d62e71cf4a308a29004f7d57glennrp                must be <= 256 */
8472d337164012450d70d62e71cf4a308a29004f7d57glennrp        {
8473d337164012450d70d62e71cf4a308a29004f7d57glennrp          if (logging != MagickFalse)
8474d337164012450d70d62e71cf4a308a29004f7d57glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8475d337164012450d70d62e71cf4a308a29004f7d57glennrp              "    Quantizing the colormap to 4-4-4");
84768e58efdecda887b08ef730d68290a61081ef2566glennrp
8477d337164012450d70d62e71cf4a308a29004f7d57glennrp          for (i=0; i<image_colors; i++)
8478d337164012450d70d62e71cf4a308a29004f7d57glennrp          {
847991d99255dd77083750426ba5463e002a586bc9a6glennrp            LBR04PacketRGB(image->colormap[i]);
8480d337164012450d70d62e71cf4a308a29004f7d57glennrp          }
8481d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8482d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
8483d337164012450d70d62e71cf4a308a29004f7d57glennrp      }
8484d337164012450d70d62e71cf4a308a29004f7d57glennrp
848582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp    if (tried_333 == MagickFalse && (image_colors == 0 || image_colors > 256))
848682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      {
848782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
848882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
848982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               "    Quantizing the background color to 3-3-3");
849082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
849182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        tried_333 = MagickTrue;
849282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
849391d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR03PacketRGB(image->background_color);
849482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
849582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (logging != MagickFalse)
849682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8497e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-3-1");
849882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
849982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        if (image->colormap == NULL)
850082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
850182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (y=0; y < (ssize_t) image->rows; y++)
850282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
850382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
850482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                exception);
850582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
85064c08aed51c5899665ade97263692328eea4af106cristy            if (r == (Quantum *) NULL)
850782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              break;
850882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
850982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            for (x=0; x < (ssize_t) image->columns; x++)
851082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            {
85114c08aed51c5899665ade97263692328eea4af106cristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
85124c08aed51c5899665ade97263692328eea4af106cristy                  LBR03RGB(r);
851382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              r++;
851482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            }
8515bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
851682b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
851782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp               break;
851882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
851982b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        }
852082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp
852182b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        else /* Should not reach this; colormap already exists and
852282b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp                must be <= 256 */
852382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp        {
852482b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          if (logging != MagickFalse)
852582b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8526e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-3-1");
852782b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          for (i=0; i<image_colors; i++)
852882b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          {
852991d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR03PacketRGB(image->colormap[i]);
853082b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp          }
8531d337164012450d70d62e71cf4a308a29004f7d57glennrp        }
8532d337164012450d70d62e71cf4a308a29004f7d57glennrp        continue;
853382b3c538ac5cfab10ee4ce71e69605dda09195a3glennrp      }
8534c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
85358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (tried_332 == MagickFalse && (image_colors == 0 || image_colors > 256))
8536c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      {
8537c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8538c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8539c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               "    Quantizing the background color to 3-3-2");
8540c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
85418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        tried_332 = MagickTrue;
85428ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
85433faa9a3fb01696daaf976d595f492cb530bffb21glennrp        /* Red and green were already done so we only quantize the blue
85443faa9a3fb01696daaf976d595f492cb530bffb21glennrp         * channel
85453faa9a3fb01696daaf976d595f492cb530bffb21glennrp         */
85463faa9a3fb01696daaf976d595f492cb530bffb21glennrp
854791d99255dd77083750426ba5463e002a586bc9a6glennrp        LBR02PacketBlue(image->background_color);
8548fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8549c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (logging != MagickFalse)
8550c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8551e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the pixel colors to 3-3-2-1");
8552fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8553c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        if (image->colormap == NULL)
8554c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8555c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (y=0; y < (ssize_t) image->rows; y++)
8556c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
8557c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            r=GetAuthenticPixels(image,0,y,image->columns,1,
8558c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                exception);
85598d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp
85604c08aed51c5899665ade97263692328eea4af106cristy            if (r == (Quantum *) NULL)
8561c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              break;
8562c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp
8563c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            for (x=0; x < (ssize_t) image->columns; x++)
8564c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            {
85654c08aed51c5899665ade97263692328eea4af106cristy              if (GetPixelAlpha(image,r) == OpaqueAlpha)
856654cf79782d2eba6612b706093f62474beb855c8dglennrp                  LBR02PixelBlue(r);
856752a479ca718756af72f96e127f8256499ab68f76glennrp              r++;
8568c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            }
8569bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8570c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp            if (SyncAuthenticPixels(image,exception) == MagickFalse)
8571c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp               break;
8572c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8573c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        }
8574c722dd852e8abe407c2846d39662f7ade9c234deglennrp
8575c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        else /* Should not reach this; colormap already exists and
8576c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp                must be <= 256 */
8577c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp        {
8578c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          if (logging != MagickFalse)
8579c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8580e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp              "    Quantizing the colormap to 3-3-2-1");
8581c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          for (i=0; i<image_colors; i++)
8582c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          {
858391d99255dd77083750426ba5463e002a586bc9a6glennrp              LBR02PacketBlue(image->colormap[i]);
8584c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp          }
8585c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      }
8586c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp      continue;
8587c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    }
8588c8c2f066877e87b2d3ece7f92a80287177717d9fglennrp    break;
85898ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
85908ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    if (image_colors == 0 || image_colors > 256)
85918ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    {
85928ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      /* Take care of special case with 256 colors + 1 transparent
85938ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * color.  We don't need to quantize to 2-3-2-1; we only need to
85948ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * eliminate one color, so we'll merge the two darkest red
85958ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       * colors (0x49, 0, 0) -> (0x24, 0, 0).
85968ca51ad2da164dabc55b192ed7884b745fde0e26glennrp       */
85978ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (ScaleQuantumToChar(image->background_color.red) == 0x49 &&
85988ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.green) == 0x00 &&
85998ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          ScaleQuantumToChar(image->background_color.blue) == 0x00)
86008ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
86018ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         image->background_color.red=ScaleCharToQuantum(0x24);
86028ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
8603bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
86048ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      if (image->colormap == NULL)
86058ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
86068ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        for (y=0; y < (ssize_t) image->rows; y++)
86078ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        {
86088ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          r=GetAuthenticPixels(image,0,y,image->columns,1,
86098ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              exception);
8610bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
86114c08aed51c5899665ade97263692328eea4af106cristy          if (r == (Quantum *) NULL)
86128ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            break;
8613bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
86148ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          for (x=0; x < (ssize_t) image->columns; x++)
86158ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          {
86164c08aed51c5899665ade97263692328eea4af106cristy            if (ScaleQuantumToChar(GetPixelRed(image,r)) == 0x49 &&
86174c08aed51c5899665ade97263692328eea4af106cristy                ScaleQuantumToChar(GetPixelGreen(image,r)) == 0x00 &&
86184c08aed51c5899665ade97263692328eea4af106cristy                ScaleQuantumToChar(GetPixelBlue(image,r)) == 0x00 &&
86194c08aed51c5899665ade97263692328eea4af106cristy                GetPixelAlpha(image,r) == OpaqueAlpha)
86208ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              {
86214c08aed51c5899665ade97263692328eea4af106cristy                SetPixelRed(image,ScaleCharToQuantum(0x24),r);
86228ca51ad2da164dabc55b192ed7884b745fde0e26glennrp              }
8623ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            r+=GetPixelChannels(image);
86248ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          }
8625bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
86268ca51ad2da164dabc55b192ed7884b745fde0e26glennrp          if (SyncAuthenticPixels(image,exception) == MagickFalse)
86278ca51ad2da164dabc55b192ed7884b745fde0e26glennrp             break;
8628bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
86298ca51ad2da164dabc55b192ed7884b745fde0e26glennrp        }
86308ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
86318ca51ad2da164dabc55b192ed7884b745fde0e26glennrp
86328ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      else
86338ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      {
86348ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         for (i=0; i<image_colors; i++)
86358ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         {
86368ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            if (ScaleQuantumToChar(image->colormap[i].red) == 0x49 &&
86378ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].green) == 0x00 &&
86388ca51ad2da164dabc55b192ed7884b745fde0e26glennrp                ScaleQuantumToChar(image->colormap[i].blue) == 0x00)
86398ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            {
86408ca51ad2da164dabc55b192ed7884b745fde0e26glennrp               image->colormap[i].red=ScaleCharToQuantum(0x24);
86418ca51ad2da164dabc55b192ed7884b745fde0e26glennrp            }
86428ca51ad2da164dabc55b192ed7884b745fde0e26glennrp         }
86438ca51ad2da164dabc55b192ed7884b745fde0e26glennrp      }
86448ca51ad2da164dabc55b192ed7884b745fde0e26glennrp    }
8645fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  }
8646fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* END OF BUILD_PALETTE */
8647fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8648fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* If we are excluding the tRNS chunk and there is transparency,
8649fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * then we must write a Gray-Alpha (color-type 4) or RGBA (color-type 6)
8650fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * PNG.
8651fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
86520e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (mng_info->ping_exclude_tRNS != MagickFalse &&
86530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     (number_transparent != 0 || number_semitransparent != 0))
86540e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    {
8655d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp      unsigned int colortype=mng_info->write_png_colortype;
86560e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
86570e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      if (ping_have_color == MagickFalse)
86580e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 5;
86590e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
86600e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      else
86610e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        mng_info->write_png_colortype = 7;
86620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
86638d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp      if (colortype != 0 &&
8664d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp         mng_info->write_png_colortype != colortype)
86650e8ea19baa0666ccfe869d19116372f60fe9230fglennrp        ping_need_colortype_warning=MagickTrue;
86660b206f5daa453dc1035db5890cabc899736dc2d0glennrp
86670e8ea19baa0666ccfe869d19116372f60fe9230fglennrp    }
86680e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
8669fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  /* See if cheap transparency is possible.  It is only possible
8670fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * when there is a single transparent color, no semitransparent
8671fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   * color, and no opaque color that has the same RGB components
86725a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * as the transparent color.  We only need this information if
86735a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * we are writing a PNG with colortype 0 or 2, and we have not
86745a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp   * excluded the tRNS chunk.
8675fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp   */
86765a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp  if (number_transparent == 1 &&
86775a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp      mng_info->write_png_colortype < 4)
8678fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    {
8679fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       ping_have_cheap_transparency = MagickTrue;
8680fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8681fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (number_semitransparent != 0)
8682fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         ping_have_cheap_transparency = MagickFalse;
8683fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8684fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else if (image_colors == 0 || image_colors > 256 ||
8685fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           image->colormap == NULL)
8686fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8687fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           ExceptionInfo
8688fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *exception;
8689fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
86904c08aed51c5899665ade97263692328eea4af106cristy           register const Quantum
8691fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             *q;
8692fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8693fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           exception=(&image->exception);
8694fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8695fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           for (y=0; y < (ssize_t) image->rows; y++)
8696fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           {
8697fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             q=GetVirtualPixels(image,0,y,image->columns,1, exception);
8698fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8699acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy             if (q == (Quantum *) NULL)
8700fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               break;
8701fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8702fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             for (x=0; x < (ssize_t) image->columns; x++)
8703fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             {
87044c08aed51c5899665ade97263692328eea4af106cristy                 if (GetPixelAlpha(image,q) != TransparentAlpha &&
8705847370c32c6b67817205f49897c43c540fd670c4glennrp                     (unsigned short) GetPixelRed(image,q) ==
8706847370c32c6b67817205f49897c43c540fd670c4glennrp                                     ping_trans_color.red &&
8707847370c32c6b67817205f49897c43c540fd670c4glennrp                     (unsigned short) GetPixelGreen(image,q) ==
8708847370c32c6b67817205f49897c43c540fd670c4glennrp                                     ping_trans_color.green &&
8709847370c32c6b67817205f49897c43c540fd670c4glennrp                     (unsigned short) GetPixelBlue(image,q) ==
8710847370c32c6b67817205f49897c43c540fd670c4glennrp                                     ping_trans_color.blue)
8711fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   {
8712fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     ping_have_cheap_transparency = MagickFalse;
8713fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                     break;
8714fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                   }
8715fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8716ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy                 q+=GetPixelChannels(image);
8717fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             }
8718bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8719fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             if (ping_have_cheap_transparency == MagickFalse)
8720fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                break;
8721fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           }
8722fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8723fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       else
8724fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
872567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            /* Assuming that image->colormap[0] is the one transparent color
872667b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             * and that all others are opaque.
872767b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp             */
8728fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp            if (image_colors > 1)
872967b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp              for (i=1; i<image_colors; i++)
873067b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                if (image->colormap[i].red == image->colormap[0].red &&
873167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].green == image->colormap[0].green &&
873267b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                    image->colormap[i].blue == image->colormap[0].blue)
8733fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  {
873467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     ping_have_cheap_transparency = MagickFalse;
873567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp                     break;
8736fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                  }
8737fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8738bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp
8739fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp       if (logging != MagickFalse)
8740fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         {
8741fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           if (ping_have_cheap_transparency == MagickFalse)
8742fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8743fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is not possible.");
8744fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
8745fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp           else
8746fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8747fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                 "   Cheap transparency is possible.");
8748fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp         }
8749fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp     }
8750fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  else
8751fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    ping_have_cheap_transparency = MagickFalse;
8752fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp
87533c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_depth=image->depth;
87543c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
87553c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  quantum_info = (QuantumInfo *) NULL;
87563c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  number_colors=0;
8757f09bdedccf9ca10bc002a946227df3367cb58d14glennrp  image_colors=(int) image->colors;
87583c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp  image_matte=image->matte;
875983c2de583a59e41b57be8036d1cf7392c01d03d7glennrp
87600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  mng_info->IsPalette=image->storage_class == PseudoClass &&
87611273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    image_colors <= 256 && image->colormap != NULL;
87623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
876352a479ca718756af72f96e127f8256499ab68f76glennrp  if ((mng_info->write_png_colortype == 4 || mng_info->write_png8) &&
876452a479ca718756af72f96e127f8256499ab68f76glennrp     (image->colors == 0 || image->colormap == NULL))
876552a479ca718756af72f96e127f8256499ab68f76glennrp    {
876652a479ca718756af72f96e127f8256499ab68f76glennrp      image_info=DestroyImageInfo(image_info);
876752a479ca718756af72f96e127f8256499ab68f76glennrp      image=DestroyImage(image);
876815e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp      (void) ThrowMagickException(&IMimage->exception,
876915e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          GetMagickModule(),CoderError,
877015e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "Cannot write PNG8 or color-type 3; colormap is NULL",
877115e0155e1d2502703b937a3454bd7907e6fd8dc7glennrp          "`%s'",IMimage->filename);
877252a479ca718756af72f96e127f8256499ab68f76glennrp#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
877352a479ca718756af72f96e127f8256499ab68f76glennrp      UnlockSemaphoreInfo(ping_semaphore);
877452a479ca718756af72f96e127f8256499ab68f76glennrp#endif
877552a479ca718756af72f96e127f8256499ab68f76glennrp      return(MagickFalse);
877652a479ca718756af72f96e127f8256499ab68f76glennrp    }
877752a479ca718756af72f96e127f8256499ab68f76glennrp
87783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
87793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate the PNG structures
87803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
87813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_USER_MEM_SUPPORTED
87823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct_2(PNG_LIBPNG_VER_STRING,image,
8783cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler,(void *) NULL,
8784cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    (png_malloc_ptr) Magick_png_malloc,(png_free_ptr) Magick_png_free);
87850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
87873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping=png_create_write_struct(PNG_LIBPNG_VER_STRING,image,
8788cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    MagickPNGErrorHandler,MagickPNGWarningHandler);
87890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
87913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping == (png_struct *) NULL)
87923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
87930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ping_info=png_create_info_struct(ping);
87950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
87963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ping_info == (png_info *) NULL)
87973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
87983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,(png_info **) NULL);
87993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
88003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_write_fn(ping,image,png_put_data,png_flush_data);
8803cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) NULL;
88043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88055af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
88063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
88083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
88093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
88103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
88113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
88123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
88133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
88153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
8816cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
88173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8818da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
8819b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
8820b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
8821b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
88223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
88233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
88253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Prepare PNG for writing.
88263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
88273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_MNG_FEATURES_SUPPORTED)
88283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
88293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
88302b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
88313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else
88323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
88333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
88343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     png_permit_empty_plte(ping,MagickTrue);
88352b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
88363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# endif
88373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
88382b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
88393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
88402b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
88414e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_width=(png_uint_32) image->columns;
88424e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  ping_height=(png_uint_32) image->rows;
88432b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
88443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8 || mng_info->write_png24 || mng_info->write_png32)
88453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
88460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png_depth != 0)
88483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=mng_info->write_png_depth;
88490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Adjust requested depth to next higher valid depth if necessary */
88513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth > 8)
88523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=16;
88530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image_depth > 4) && (image_depth < 8))
88553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=8;
88560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_depth == 3)
88583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_depth=4;
88590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
88603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
88613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8863e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    width=%.20g",(double) ping_width);
88643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8865e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    height=%.20g",(double) ping_height);
88663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8867e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_matte=%.20g",(double) image->matte);
88683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88698640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth=%.20g",(double) image->depth);
88703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
88718640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    Tentative ping_bit_depth=%.20g",(double) image_depth);
88723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
88738640fb5e9b1094f35f8beab436f81661b8a99448glennrp
88743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  save_image_depth=image_depth;
88755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_bit_depth=(png_byte) save_image_depth;
8876dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
887726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
88783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_pHYs_SUPPORTED)
887926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
888026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
88813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->x_resolution != 0) && (image->y_resolution != 0) &&
88823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (!mng_info->write_mng || !mng_info->equal_physs))
88833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
88840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
8885dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8886dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp            "    Setting up pHYs chunk");
88873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
88883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
88893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8890dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8891823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=
8892823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->x_resolution+0.5)/2.54);
8893823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=
8894823b55c200d7fc1818ab539b036a9c24feaecda8glennrp             (png_uint_32) ((100.0*image->y_resolution+0.5)/2.54);
88953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8896dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
88973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (image->units == PixelsPerCentimeterResolution)
88983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8899dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_METER;
8900823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_x_resolution=(png_uint_32) (100.0*image->x_resolution+0.5);
8901823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          ping_pHYs_y_resolution=(png_uint_32) (100.0*image->y_resolution+0.5);
89023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8903991d11dd9c33e65872778b81aff1347cd2878154glennrp
89043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
89053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8906dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_unit_type=PNG_RESOLUTION_UNKNOWN;
8907dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_x_resolution=(png_uint_32) image->x_resolution;
8908dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp          ping_pHYs_y_resolution=(png_uint_32) image->y_resolution;
89093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8910991d11dd9c33e65872778b81aff1347cd2878154glennrp
8911823b55c200d7fc1818ab539b036a9c24feaecda8glennrp      if (logging != MagickFalse)
8912823b55c200d7fc1818ab539b036a9c24feaecda8glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8913823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          "    Set up PNG pHYs chunk: xres: %.20g, yres: %.20g, units: %d.",
8914823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (double) ping_pHYs_x_resolution,(double) ping_pHYs_y_resolution,
8915823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          (int) ping_pHYs_unit_type);
8916991d11dd9c33e65872778b81aff1347cd2878154glennrp       ping_have_pHYs = MagickTrue;
89173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
891826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
89193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8920a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
892126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
892226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
8923a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  if ((!mng_info->adjoin || !mng_info->equal_backgrounds))
89243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8925a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       unsigned int
8926a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         mask;
8927a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
8928a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       mask=0xffff;
8929a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 8)
8930a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x00ff;
89310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8932a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 4)
8933a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x000f;
89340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8935a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 2)
8936a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0003;
89370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8938a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       if (ping_bit_depth == 1)
8939a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          mask=0x0001;
89400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8941a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.red=(png_uint_16)
8942a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.red) & mask);
89430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8944a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.green=(png_uint_16)
8945a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.green) & mask);
89460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8947a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp       ping_background.blue=(png_uint_16)
8948a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         (ScaleQuantumToShort(image->background_color.blue) & mask);
8949c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
8950c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp       ping_background.gray=(png_uint_16) ping_background.green;
89510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
89520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  if (logging != MagickFalse)
89543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    {
89553b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89563b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    Setting up bKGD chunk (1)");
8957c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
8958c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          "      background_color index is %d",
8959c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          (int) ping_background.index);
89603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
89613b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89623b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          "    ping_bit_depth=%d",ping_bit_depth);
89633b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp    }
89640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  ping_have_bKGD = MagickTrue;
896626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
89673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
89693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Select the color type.
89703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
89713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  matte=image_matte;
89723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  old_bit_depth=0;
89730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89741273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp  if (mng_info->IsPalette && mng_info->write_png8)
89753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
89760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
8977fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp      /* To do: make this a function cause it's used twice, except
89780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         for reducing the sample depth from 8. */
89790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      number_colors=image_colors;
89818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
89828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_tRNS=MagickFalse;
89830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      /*
89850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        Set image palette.
89860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      */
89870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
89880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89890fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (logging != MagickFalse)
89900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
89910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "  Setting up PLTE chunk with %d colors (%d)",
8992f09bdedccf9ca10bc002a946227df3367cb58d14glennrp            number_colors, image_colors);
89930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
89940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      for (i=0; i < (ssize_t) number_colors; i++)
89950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      {
89960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
89970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
89980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
89990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        if (logging != MagickFalse)
90000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
900167b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#if MAGICKCORE_QUANTUM_DEPTH == 8
90020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            "    %3ld (%3d,%3d,%3d)",
900367b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#else
900467b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp            "    %5ld (%5d,%5d,%5d)",
900567b9c1a76a0be5ad88b138c4f46dd860b272e1bcglennrp#endif
90060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (long) i,palette[i].red,palette[i].green,palette[i].blue);
90073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      }
90092b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
90108bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_have_PLTE=MagickTrue;
90118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      image_depth=ping_bit_depth;
90128bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      ping_num_trans=0;
90135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
901458e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp      if (matte != MagickFalse)
90158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      {
90160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          /*
90170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            Identify which colormap entry is transparent.
90180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          */
90190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          assert(number_colors <= 256);
90208bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          assert(image->colormap != NULL);
90213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
90228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (i=0; i < (ssize_t) number_transparent; i++)
90238bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_trans_alpha[i]=0;
90240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90262cc891a179d622dde7bbb8854138851e828bc6eaglennrp          ping_num_trans=(unsigned short) (number_transparent +
90278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             number_semitransparent);
90280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_num_trans == 0)
90300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             ping_have_tRNS=MagickFalse;
90310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
90338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp             ping_have_tRNS=MagickTrue;
90348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      }
90350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90361273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp      if (ping_exclude_bKGD == MagickFalse)
90374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      {
90381273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp       /*
90391273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        * Identify which colormap entry is the background color.
90401273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp        */
90411273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp
90424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors-1L,1L); i++)
90434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (IsPNGColorEqual(ping_background,image->colormap[i]))
90444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            break;
90450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        ping_background.index=(png_byte) i;
9047c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp
9048c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        if (logging != MagickFalse)
9049c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          {
9050c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9051c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 "      background_color index is %d",
9052c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                 (int) ping_background.index);
9053c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          }
90544f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      }
90553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } /* end of write_png8 */
90560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90577e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png24 || mng_info->write_png_colortype == 3)
90583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
90605af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
90613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90637e65e93c71716f2a5c03c0808adedae21d519fb2glennrp  else if (mng_info->write_png32 || mng_info->write_png_colortype == 7)
90643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickTrue;
90665af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
90673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
90680fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90698bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else /* mng_info->write_pngNN not specified */
90703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
90715af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      image_depth=ping_bit_depth;
90720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      if (mng_info->write_png_colortype != 0)
90743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90755af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_color_type=(png_byte) mng_info->write_png_colortype-1;
90760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90775af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
90785af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
90793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            image_matte=MagickTrue;
90802cc891a179d622dde7bbb8854138851e828bc6eaglennrp
90818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
90828bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            image_matte=MagickFalse;
90837c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
90847c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (logging != MagickFalse)
90857c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90867c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             "   PNG colortype %d was specified:",(int) ping_color_type);
90873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
90880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
90897c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp      else /* write_png_colortype not specified */
90903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
90913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
90923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
90933c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Selecting PNG colortype:");
90940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9095d6bf1617e99df0272b231855a933a74e99b6578fglennrp          ping_color_type=(png_byte) ((matte != MagickFalse)?
90968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            PNG_COLOR_TYPE_RGB_ALPHA:PNG_COLOR_TYPE_RGB);
90970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9098d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorType)
90993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
91013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickFalse;
91023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9104d6bf1617e99df0272b231855a933a74e99b6578fglennrp          if (image_info->type == TrueColorMatteType)
91053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91065af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB_ALPHA;
91073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              image_matte=MagickTrue;
91083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
91090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91105aa37f69df93407ddf94afdfd2504f708d8b3242glennrp          if (image_info->type == PaletteType ||
91115aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              image_info->type == PaletteMatteType)
91125aa37f69df93407ddf94afdfd2504f708d8b3242glennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
91135aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
91147c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0 &&
91157c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             (image_info->type == UndefinedType ||
91167c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp             image_info->type == OptimizeType))
91173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
91185aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              if (ping_have_color == MagickFalse)
91198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
91205aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
91215aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
91225aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY;
91235aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
91245aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
91250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91260b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
91275aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
91285aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_GRAY_ALPHA;
91295aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
91305aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
91318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
91325aa37f69df93407ddf94afdfd2504f708d8b3242glennrp              else
91335aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                {
91345aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                  if (image_matte == MagickFalse)
91355aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
91365aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGB;
91375aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickFalse;
91385aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
91398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
91400b206f5daa453dc1035db5890cabc899736dc2d0glennrp                  else
91415aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    {
91425aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      ping_color_type=(png_byte) PNG_COLOR_TYPE_RGBA;
91435aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                      image_matte=MagickTrue;
91445aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                    }
91455aa37f69df93407ddf94afdfd2504f708d8b3242glennrp                 }
91460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            }
91475aa37f69df93407ddf94afdfd2504f708d8b3242glennrp
91483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
91503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
915126c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
91528640fb5e9b1094f35f8beab436f81661b8a99448glennrp         "    Selected PNG colortype=%d",ping_color_type);
915326c990a974947ce90bfb1d08bcd8794bf85f7a65glennrp
91545af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_bit_depth < 8)
91550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
91560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
91570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB ||
91580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              ping_color_type == PNG_COLOR_TYPE_RGB_ALPHA)
91590fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_bit_depth=8;
91600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
91613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9162d6bf1617e99df0272b231855a933a74e99b6578fglennrp      old_bit_depth=ping_bit_depth;
9163d6bf1617e99df0272b231855a933a74e99b6578fglennrp
91645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_GRAY)
91653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
91668d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp          if (image->matte == MagickFalse && ping_have_non_bw == MagickFalse)
91678d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp             ping_bit_depth=1;
91683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
91698640fb5e9b1094f35f8beab436f81661b8a99448glennrp
91705af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      if (ping_color_type == PNG_COLOR_TYPE_PALETTE)
91713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
917235ef824baa82511126ff0072ae30eee0da9c05a3cristy           size_t one = 1;
91735af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_bit_depth=1;
91740f111984738842d27d04aed2a3f823d82a943506glennrp
91750f111984738842d27d04aed2a3f823d82a943506glennrp           if (image->colors == 0)
91760f111984738842d27d04aed2a3f823d82a943506glennrp           {
91770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              /* DO SOMETHING */
9178c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              (void) ThrowMagickException(&image->exception,
91790f111984738842d27d04aed2a3f823d82a943506glennrp                 GetMagickModule(),CoderError,
9180c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                "image has 0 colors", "`%s'","");
91810f111984738842d27d04aed2a3f823d82a943506glennrp           }
91820f111984738842d27d04aed2a3f823d82a943506glennrp
918335ef824baa82511126ff0072ae30eee0da9c05a3cristy           while ((int) (one << ping_bit_depth) < (ssize_t) image_colors)
91845af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth <<= 1;
9185d6bf1617e99df0272b231855a933a74e99b6578fglennrp        }
91863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9187d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (logging != MagickFalse)
9188d6bf1617e99df0272b231855a933a74e99b6578fglennrp         {
9189d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9190d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Number of colors: %.20g",(double) image_colors);
91910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9192d6bf1617e99df0272b231855a933a74e99b6578fglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9193d6bf1617e99df0272b231855a933a74e99b6578fglennrp            "    Tentative PNG bit depth: %d",ping_bit_depth);
9194d6bf1617e99df0272b231855a933a74e99b6578fglennrp         }
91950fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9196d6bf1617e99df0272b231855a933a74e99b6578fglennrp      if (ping_bit_depth < (int) mng_info->write_png_depth)
9197d6bf1617e99df0272b231855a933a74e99b6578fglennrp         ping_bit_depth = mng_info->write_png_depth;
91983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
91992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
92005af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  image_depth=ping_bit_depth;
92012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
92023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
92033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9205e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Tentative PNG color type: %.20g",(double) ping_color_type);
92060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9208e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_info->type: %.20g",(double) image_info->type);
92090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9211e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    image_depth: %.20g",(double) image_depth);
92120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
92143c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp
92158640fb5e9b1094f35f8beab436f81661b8a99448glennrp        "    image->depth: %.20g",(double) image->depth);
92168640fb5e9b1094f35f8beab436f81661b8a99448glennrp
92178640fb5e9b1094f35f8beab436f81661b8a99448glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9218e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    ping_bit_depth: %.20g",(double) ping_bit_depth);
92193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
92203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
922158e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (matte != MagickFalse)
92223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
92234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if (mng_info->IsPalette)
92244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
92257c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp          if (mng_info->write_png_colortype == 0)
92267c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            {
92277c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
92282b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
92297c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (ping_have_color != MagickFalse)
92307c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                 ping_color_type=PNG_COLOR_TYPE_RGBA;
92317c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp            }
92322b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
92333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
92344f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp           * Determine if there is any transparent color.
92353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
92364f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (number_transparent + number_semitransparent == 0)
92374f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
92384f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
92394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                No transparent pixels are present.  Change 4 or 6 to 0 or 2.
92404f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              */
9241a6a0663bea94c73cf424f0b49076e7c037d084d4glennrp
92424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              image_matte=MagickFalse;
92437c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp
92447c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
92457c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type&=0x03;
92464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
92470fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          else
92494f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
92504f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              unsigned int
9251bb4f99d3d6ed6a8eee38324baf473c45e4f644e4glennrp                mask;
92523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
92534f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              mask=0xffff;
92540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92554f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 8)
92564f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x00ff;
92570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92584f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 4)
92594f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x000f;
92600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92614f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 2)
92624f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0003;
92630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92644f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (ping_bit_depth == 1)
92654f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                 mask=0x0001;
92660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92674f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.red=(png_uint_16)
92684f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].red) & mask);
92690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92704f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.green=(png_uint_16)
92714f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].green) & mask);
92720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92734f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.blue=(png_uint_16)
92744f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (ScaleQuantumToShort(image->colormap[0].blue) & mask);
92750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92764f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.gray=(png_uint_16)
92774c08aed51c5899665ade97263692328eea4af106cristy                (ScaleQuantumToShort(GetPixelPacketIntensity(
92784f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                   image->colormap)) & mask);
92790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92804f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_trans_color.index=(png_byte) 0;
92810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92824f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              ping_have_tRNS=MagickTrue;
92834f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
92840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
92854f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
92864f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
92874f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              /*
9288fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * Determine if there is one and only one transparent color
9289fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               * and if so if it is fully transparent.
9290fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp               */
9291fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp              if (ping_have_cheap_transparency == MagickFalse)
9292fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp                ping_have_tRNS=MagickFalse;
92934f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
92942b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
92954f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          if (ping_have_tRNS != MagickFalse)
92964f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            {
92977c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp              if (mng_info->write_png_colortype == 0)
92987c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp                ping_color_type &= 0x03;  /* changes 4 or 6 to 0 or 2 */
92990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93004f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              if (image_depth == 8)
93014f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                {
93024f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.red&=0xff;
93034f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.green&=0xff;
93044f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.blue&=0xff;
93054f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  ping_trans_color.gray&=0xff;
93064f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                }
93074f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            }
93084f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        }
93094f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      else
93104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp        {
93113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image_depth == 8)
93123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
93135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.red&=0xff;
93145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.green&=0xff;
93155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.blue&=0xff;
93165af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp              ping_trans_color.gray&=0xff;
93173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
93183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
93193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
93208640fb5e9b1094f35f8beab436f81661b8a99448glennrp
93213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    matte=image_matte;
93220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93232e09f55407bbe197cbaf4f88b1d7265f62d7f6c7glennrp    if (ping_have_tRNS != MagickFalse)
93243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_matte=MagickFalse;
93250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
932639992b4dd9b12ef752d55b8e402c069698851f72glennrp    if ((mng_info->IsPalette) &&
93273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE &&
93288d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        ping_have_color == MagickFalse &&
93298d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp        (image_matte == MagickFalse || image_depth >= 8))
93303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
933135ef824baa82511126ff0072ae30eee0da9c05a3cristy        size_t one=1;
93320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_matte != MagickFalse)
93349c1eb0729653219b9da9037e044501a6dce79d10glennrp          ping_color_type=PNG_COLOR_TYPE_GRAY_ALPHA;
93350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93367c4c9e67499f5a8e5cfd4148a3424bacd8fc635bglennrp        else if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_GRAY_ALPHA)
93373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93385af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=PNG_COLOR_TYPE_GRAY;
93394f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
93403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (save_image_depth == 16 && image_depth == 8)
93414f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
93424f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                if (logging != MagickFalse)
93434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  {
93444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
93454f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                        "  Scaling ping_trans_color (0)");
93464f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  }
93474f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                    ping_trans_color.gray*=0x0101;
93484f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
93493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
93500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > MAGICKCORE_QUANTUM_DEPTH)
93523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=MAGICKCORE_QUANTUM_DEPTH;
93530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9354136ee3aa5987c7418c835f7ee741e1af1dadb113glennrp        if ((image_colors == 0) ||
9355d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp             ((ssize_t) (image_colors-1) > (ssize_t) MaxColormapSize))
9356f09bdedccf9ca10bc002a946227df3367cb58d14glennrp          image_colors=(int) (one << image_depth);
93570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth > 8)
93595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          ping_bit_depth=16;
93600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
93613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
93623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
93635af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_bit_depth=8;
93645af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
93653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
93663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if(!mng_info->write_png_depth)
93673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  {
93685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                    ping_bit_depth=1;
93690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
937035ef824baa82511126ff0072ae30eee0da9c05a3cristy                    while ((int) (one << ping_bit_depth)
9371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                        < (ssize_t) image_colors)
93725af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                      ping_bit_depth <<= 1;
93733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  }
93743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
93752b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
93760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            else if (ping_color_type ==
93770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                PNG_COLOR_TYPE_GRAY && image_colors < 17 &&
93783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->IsPalette)
93793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
93803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              /* Check if grayscale is reducible */
93811a0aaa639fb2360f2db93f9b0ed2b42ef6d2106dglennrp
93823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                int
93833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_4_ok=MagickTrue,
93843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_2_ok=MagickTrue,
93853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  depth_1_ok=MagickTrue;
93863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9387bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image_colors; i++)
93883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
93893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   unsigned char
93903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     intensity;
93913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   intensity=ScaleQuantumToChar(image->colormap[i].red);
93933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
93943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   if ((intensity & 0x0f) != ((intensity & 0xf0) >> 4))
93953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_4_ok=depth_2_ok=depth_1_ok=MagickFalse;
93963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   else if ((intensity & 0x03) != ((intensity & 0x0c) >> 2))
93973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_2_ok=depth_1_ok=MagickFalse;
93984bf89731a90c6e03598950223e19e7be7b95d630glennrp                   else if ((intensity & 0x01) != ((intensity & 0x02) >> 1))
93993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     depth_1_ok=MagickFalse;
94003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
94012b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (depth_1_ok && mng_info->write_png_depth <= 1)
94039c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=1;
94040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_2_ok && mng_info->write_png_depth <= 2)
94069c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=2;
94070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else if (depth_4_ok && mng_info->write_png_depth <= 4)
94099c1eb0729653219b9da9037e044501a6dce79d10glennrp                  ping_bit_depth=4;
94103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
94113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
94122b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
94135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          image_depth=ping_bit_depth;
94143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
94150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
94170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->IsPalette)
94193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
942017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
942117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
94223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth <= 8)
94233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
94243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
94253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Set image palette.
94263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
94275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_color_type=(png_byte) PNG_COLOR_TYPE_PALETTE;
94280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
942958e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (mng_info->have_write_global_plte && matte == MagickFalse)
94303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
94319c1eb0729653219b9da9037e044501a6dce79d10glennrp                png_set_PLTE(ping,ping_info,NULL,0);
94320fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94333b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
94349c1eb0729653219b9da9037e044501a6dce79d10glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
94359c1eb0729653219b9da9037e044501a6dce79d10glennrp                    "  Setting up empty PLTE chunk");
94363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
94370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
94393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9440bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) number_colors; i++)
94413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
94423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].red=ScaleQuantumToChar(image->colormap[i].red);
94433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].green=ScaleQuantumToChar(image->colormap[i].green);
94443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  palette[i].blue=ScaleQuantumToChar(image->colormap[i].blue);
94453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
94460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94473b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse)
94483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
944998156a3a465a004545e39434c63052b955a74d1cglennrp                    "  Setting up PLTE chunk with %d colors",
9450f09bdedccf9ca10bc002a946227df3367cb58d14glennrp                    number_colors);
94510fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
945239992b4dd9b12ef752d55b8e402c069698851f72glennrp                ping_have_PLTE=MagickTrue;
94533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
94540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /* color_type is PNG_COLOR_TYPE_PALETTE */
9456d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (mng_info->write_png_depth == 0)
94573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
9458befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                size_t
9459befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                  one;
9460befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy
94615af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                ping_bit_depth=1;
9462befe4d21bf21c8f8fb5c8cc01fe60fe4accac47fcristy                one=1;
94630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9464d17915c2c5a29b7f778217765f0f2d354c829e9eglennrp                while ((one << ping_bit_depth) < (ssize_t) number_colors)
94655af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth <<= 1;
94663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
94670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
94685af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_num_trans=0;
94690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
947058e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp            if (matte != MagickFalse)
94710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
94720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                /*
9473d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 * Set up trans_colors array.
9474d6bf1617e99df0272b231855a933a74e99b6578fglennrp                 */
94750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                assert(number_colors <= 256);
94763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9477d6bf1617e99df0272b231855a933a74e99b6578fglennrp                ping_num_trans=(unsigned short) (number_transparent +
9478d6bf1617e99df0272b231855a933a74e99b6578fglennrp                  number_semitransparent);
94793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
94800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                if (ping_num_trans == 0)
94810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  ping_have_tRNS=MagickFalse;
94820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9483d6bf1617e99df0272b231855a933a74e99b6578fglennrp                else
94840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  {
9485c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    if (logging != MagickFalse)
9486c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      {
9487c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9488c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                          "  Scaling ping_trans_color (1)");
9489c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                      }
9490d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    ping_have_tRNS=MagickTrue;
9491d6bf1617e99df0272b231855a933a74e99b6578fglennrp
9492d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    for (i=0; i < ping_num_trans; i++)
9493d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    {
94944c08aed51c5899665ade97263692328eea4af106cristy                       ping_trans_alpha[i]= (png_byte)
94954c08aed51c5899665ade97263692328eea4af106cristy                         ScaleQuantumToChar(image->colormap[i].alpha);
9496d6bf1617e99df0272b231855a933a74e99b6578fglennrp                    }
94970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  }
94980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
94993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
95033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9504c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
95053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image_depth < 8)
95063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_depth=8;
95070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
95083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((save_image_depth == 16) && (image_depth == 8))
95093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
95104f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
95114f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
95124f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95134f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    Scaling ping_trans_color from (%d,%d,%d)",
95144f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
95154f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
95164f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
95174f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
95184f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
95195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.red*=0x0101;
95205af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.green*=0x0101;
95215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.blue*=0x0101;
95225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            ping_trans_color.gray*=0x0101;
95234f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp
95244f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp            if (logging != MagickFalse)
95254f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              {
95264f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95274f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  "    to (%d,%d,%d)",
95284f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.red,
95294f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.green,
95304f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp                  (int) ping_trans_color.blue);
95314f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp              }
95323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
95333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
95343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95354383ec8c3c8811128f5a8a034d67c47db5e7e75acristy    if (ping_bit_depth <  (ssize_t) mng_info->write_png_depth)
95364383ec8c3c8811128f5a8a034d67c47db5e7e75acristy         ping_bit_depth =  (ssize_t) mng_info->write_png_depth;
95372cc891a179d622dde7bbb8854138851e828bc6eaglennrp
95383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
95393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Adjust background and transparency samples in sub-8-bit grayscale files.
95403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
95415af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp    if (ping_bit_depth < 8 && ping_color_type ==
95423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG_COLOR_TYPE_GRAY)
95433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
95443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         png_uint_16
95453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           maxval;
95463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
954735ef824baa82511126ff0072ae30eee0da9c05a3cristy         size_t
954835ef824baa82511126ff0072ae30eee0da9c05a3cristy           one=1;
954935ef824baa82511126ff0072ae30eee0da9c05a3cristy
955022ffd97a7a54140ebcfe886af90cbdb7bfe41e89cristy         maxval=(png_uint_16) ((one << ping_bit_depth)-1);
95513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95524f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp         if (ping_exclude_bKGD == MagickFalse)
955326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         {
95543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9555a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp         ping_background.gray=(png_uint_16)
9556847370c32c6b67817205f49897c43c540fd670c4glennrp           ((maxval/255.)*((GetPixelPacketIntensity(&image->background_color)))
9557847370c32c6b67817205f49897c43c540fd670c4glennrp                                    +.5);
95583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
95603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95613c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp             "  Setting up bKGD chunk (2)");
9562c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9563c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp             "      background_color index is %d",
9564c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp             (int) ping_background.index);
95653b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
9566991d11dd9c33e65872778b81aff1347cd2878154glennrp         ping_have_bKGD = MagickTrue;
956726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp         }
95683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
95693e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
95703e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95713e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "  Scaling ping_trans_color.gray from %d",
95723e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             (int)ping_trans_color.gray);
95733e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
95749be9b1cfe4c5ead507b2ad633cced4321db3c806glennrp         ping_trans_color.gray=(png_uint_16) ((maxval/255.)*(
95753e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           ping_trans_color.gray)+.5);
95763e3e20f27f74686a93873f25b015e0e8e40f451dglennrp
95773e3e20f27f74686a93873f25b015e0e8e40f451dglennrp         if (logging != MagickFalse)
95783e3e20f27f74686a93873f25b015e0e8e40f451dglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
95793e3e20f27f74686a93873f25b015e0e8e40f451dglennrp             "      to %d", (int)ping_trans_color.gray);
95803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
958117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
958226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
958326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
95841273f7b031edcb07e2ee4835455712ebdd0b2f60glennrp    if (mng_info->IsPalette && (int) ping_color_type == PNG_COLOR_TYPE_PALETTE)
958517a1485544c62993fc7a94e343c87fed5f3e6407glennrp      {
958617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        /*
958717a1485544c62993fc7a94e343c87fed5f3e6407glennrp           Identify which colormap entry is the background color.
958817a1485544c62993fc7a94e343c87fed5f3e6407glennrp        */
958917a1485544c62993fc7a94e343c87fed5f3e6407glennrp
959017a1485544c62993fc7a94e343c87fed5f3e6407glennrp        number_colors=image_colors;
959117a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9592a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp        for (i=0; i < (ssize_t) MagickMax(1L*number_colors,1L); i++)
9593a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          if (IsPNGColorEqual(image->background_color,image->colormap[i]))
959417a1485544c62993fc7a94e343c87fed5f3e6407glennrp            break;
959517a1485544c62993fc7a94e343c87fed5f3e6407glennrp
959617a1485544c62993fc7a94e343c87fed5f3e6407glennrp        ping_background.index=(png_byte) i;
959717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
95983b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp        if (logging != MagickFalse)
95990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
96000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Setting up bKGD chunk with index=%d",(int) i);
96020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          }
9603a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
960413d07043243e0c8c151aad7db5240b75e76ca281cristy        if (i < (ssize_t) number_colors)
9605a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          {
96060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp            ping_have_bKGD = MagickTrue;
96073b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
96083b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
96090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              {
96100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  "     background   =(%d,%d,%d)",
96120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.red,
96130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.green,
96140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                        (int) ping_background.blue);
96150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              }
9616a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp          }
961717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
9618d6bf1617e99df0272b231855a933a74e99b6578fglennrp        else  /* Can't happen */
96193c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          {
96203b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse)
96213b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96223b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                  "      No room in PLTE to add bKGD color");
96233c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp            ping_have_bKGD = MagickFalse;
96243c21811cab8a3b168295e3f0da1909c4e2a7da15glennrp          }
962517a1485544c62993fc7a94e343c87fed5f3e6407glennrp      }
962626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
962717a1485544c62993fc7a94e343c87fed5f3e6407glennrp
96283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
96293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96305af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp      "    PNG color type: %d",ping_color_type);
96313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
96323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize compression level and filtering.
96333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
96343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
96350fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    {
96360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "  Setting up deflate compression");
96380fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        "    Compression buffer size: 32768");
96410fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
96420fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_compression_buffer_size(ping,32768L);
96440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
96463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
96473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "    Compression mem level: 9");
96480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96494054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  png_set_compression_mem_level(ping, 9);
96504054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
965110d739ef54404090a55cb8977fc51f85cafa81a5glennrp  /* Untangle the "-quality" setting:
965210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
965310d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Undefined is 0; the default is used.
965410d739ef54404090a55cb8977fc51f85cafa81a5glennrp     Default is 75
965510d739ef54404090a55cb8977fc51f85cafa81a5glennrp
965610d739ef54404090a55cb8977fc51f85cafa81a5glennrp     10's digit:
965710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
965810d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0: Use Z_HUFFMAN_ONLY strategy with the
965910d739ef54404090a55cb8977fc51f85cafa81a5glennrp           zlib default compression level
966010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
966110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        1-9: the zlib compression level
966210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
966310d739ef54404090a55cb8977fc51f85cafa81a5glennrp     1's digit:
966410d739ef54404090a55cb8977fc51f85cafa81a5glennrp
966510d739ef54404090a55cb8977fc51f85cafa81a5glennrp        0-4: the PNG filter method
966610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
966710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        5:   libpng adaptive filtering if compression level > 5
966810d739ef54404090a55cb8977fc51f85cafa81a5glennrp             libpng filter type "none" if compression level <= 5
966910d739ef54404090a55cb8977fc51f85cafa81a5glennrp                or if image is grayscale or palette
967010d739ef54404090a55cb8977fc51f85cafa81a5glennrp
967110d739ef54404090a55cb8977fc51f85cafa81a5glennrp        6:   libpng adaptive filtering
967210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
967310d739ef54404090a55cb8977fc51f85cafa81a5glennrp        7:   "LOCO" filtering (intrapixel differing) if writing
967410d739ef54404090a55cb8977fc51f85cafa81a5glennrp             a MNG, othewise "none".  Did not work in IM-6.7.0-9
967510d739ef54404090a55cb8977fc51f85cafa81a5glennrp             and earlier because of a missing "else".
967610d739ef54404090a55cb8977fc51f85cafa81a5glennrp
967710d739ef54404090a55cb8977fc51f85cafa81a5glennrp        8:   Z_RLE strategy, all filters
96781868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
967910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
968010d739ef54404090a55cb8977fc51f85cafa81a5glennrp        9:   Z_RLE strategy, no PNG filters
96811868258559ddf946fa73ef72dd43507b32623705glennrp             Unused prior to IM-6.7.0-10, was same as 6
968210d739ef54404090a55cb8977fc51f85cafa81a5glennrp
968310d739ef54404090a55cb8977fc51f85cafa81a5glennrp    Note that using the -quality option, not all combinations of
968410d739ef54404090a55cb8977fc51f85cafa81a5glennrp    PNG filter type, zlib compression level, and zlib compression
96855e6be1e6a77c230e4a204fa9163d873104730c35cristy    strategy are possible.  This will be addressed soon in a
96864054bfbdca478fe065f01d7f8285f7c173ccfcfccristy    release that accomodates "-define PNG:compression-strategy", etc.
968710d739ef54404090a55cb8977fc51f85cafa81a5glennrp
968810d739ef54404090a55cb8977fc51f85cafa81a5glennrp   */
968910d739ef54404090a55cb8977fc51f85cafa81a5glennrp
96903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quality=image->quality == UndefinedCompressionQuality ? 75UL :
96913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image->quality;
96920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
96931868258559ddf946fa73ef72dd43507b32623705glennrp  if (quality <= 9)
96941868258559ddf946fa73ef72dd43507b32623705glennrp    {
96951868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_png_compression_strategy == 0)
96961868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
96971868258559ddf946fa73ef72dd43507b32623705glennrp    }
96981868258559ddf946fa73ef72dd43507b32623705glennrp
96991868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_level == 0)
97003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
97023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        level;
97033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9704bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      level=(int) MagickMin((ssize_t) quality/10,9);
97050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97061868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_level = level+1;
97071868258559ddf946fa73ef72dd43507b32623705glennrp    }
97080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97091868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy == 0)
97101868258559ddf946fa73ef72dd43507b32623705glennrp    {
97111868258559ddf946fa73ef72dd43507b32623705glennrp        if ((quality %10) == 8 || (quality %10) == 9)
97121868258559ddf946fa73ef72dd43507b32623705glennrp            mng_info->write_png_compression_strategy=Z_RLE;
97133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97151868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 0)
97161868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter=((int) quality % 10) + 1;
97171868258559ddf946fa73ef72dd43507b32623705glennrp
97181868258559ddf946fa73ef72dd43507b32623705glennrp  if (logging != MagickFalse)
97193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
97201868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_level)
97213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97221868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression level:    %d",
97231868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_level-1);
97240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97251868258559ddf946fa73ef72dd43507b32623705glennrp     if (mng_info->write_png_compression_strategy)
97261868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97271868258559ddf946fa73ef72dd43507b32623705glennrp          "    Compression strategy: %d",
97281868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_strategy-1);
97290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97301868258559ddf946fa73ef72dd43507b32623705glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97311868258559ddf946fa73ef72dd43507b32623705glennrp          "  Setting up filtering");
97323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97334054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        if (mng_info->write_png_compression_filter == 6)
973410d739ef54404090a55cb8977fc51f85cafa81a5glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97351868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: ADAPTIVE");
97364054bfbdca478fe065f01d7f8285f7c173ccfcfccristy        else if (mng_info->write_png_compression_filter == 0 ||
97374054bfbdca478fe065f01d7f8285f7c173ccfcfccristy                 mng_info->write_png_compression_filter == 1)
97381868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97391868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: NONE");
97401868258559ddf946fa73ef72dd43507b32623705glennrp        else
97411868258559ddf946fa73ef72dd43507b32623705glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
97421868258559ddf946fa73ef72dd43507b32623705glennrp            "    Base filter method: %d",
97431868258559ddf946fa73ef72dd43507b32623705glennrp            (int) mng_info->write_png_compression_filter-1);
97443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
97450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97461868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_level != 0)
97471868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_level(ping,mng_info->write_png_compression_level-1);
97480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97491868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_filter == 6)
97501868258559ddf946fa73ef72dd43507b32623705glennrp    {
97511868258559ddf946fa73ef72dd43507b32623705glennrp      if (((int) ping_color_type == PNG_COLOR_TYPE_GRAY) ||
97521868258559ddf946fa73ef72dd43507b32623705glennrp         ((int) ping_color_type == PNG_COLOR_TYPE_PALETTE) ||
97531868258559ddf946fa73ef72dd43507b32623705glennrp         (quality < 50))
97541868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
97551868258559ddf946fa73ef72dd43507b32623705glennrp      else
97561868258559ddf946fa73ef72dd43507b32623705glennrp        png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
97571868258559ddf946fa73ef72dd43507b32623705glennrp     }
97584054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  else if (mng_info->write_png_compression_filter == 7 ||
97591868258559ddf946fa73ef72dd43507b32623705glennrp      mng_info->write_png_compression_filter == 10)
97601868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_ALL_FILTERS);
976110d739ef54404090a55cb8977fc51f85cafa81a5glennrp
97621868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 8)
97631868258559ddf946fa73ef72dd43507b32623705glennrp    {
97641868258559ddf946fa73ef72dd43507b32623705glennrp#if defined(PNG_MNG_FEATURES_SUPPORTED) && defined(PNG_INTRAPIXEL_DIFFERENCING)
97651868258559ddf946fa73ef72dd43507b32623705glennrp      if (mng_info->write_mng)
97661868258559ddf946fa73ef72dd43507b32623705glennrp      {
97671868258559ddf946fa73ef72dd43507b32623705glennrp         if (((int) ping_color_type == PNG_COLOR_TYPE_RGB) ||
97681868258559ddf946fa73ef72dd43507b32623705glennrp             ((int) ping_color_type == PNG_COLOR_TYPE_RGBA))
97691868258559ddf946fa73ef72dd43507b32623705glennrp        ping_filter_method=PNG_INTRAPIXEL_DIFFERENCING;
97701868258559ddf946fa73ef72dd43507b32623705glennrp      }
97711868258559ddf946fa73ef72dd43507b32623705glennrp#endif
97724054bfbdca478fe065f01d7f8285f7c173ccfcfccristy      png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
97731868258559ddf946fa73ef72dd43507b32623705glennrp    }
97740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97751868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter == 9)
97761868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,PNG_NO_FILTERS);
97770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97781868258559ddf946fa73ef72dd43507b32623705glennrp  else if (mng_info->write_png_compression_filter != 0)
97791868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_filter(ping,PNG_FILTER_TYPE_BASE,
97801868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_filter-1);
97810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
97821868258559ddf946fa73ef72dd43507b32623705glennrp  if (mng_info->write_png_compression_strategy != 0)
97831868258559ddf946fa73ef72dd43507b32623705glennrp    png_set_compression_strategy(ping,
97841868258559ddf946fa73ef72dd43507b32623705glennrp       mng_info->write_png_compression_strategy-1);
97852b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
97863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
97874054bfbdca478fe065f01d7f8285f7c173ccfcfccristy  if ((ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse) &&
97884054bfbdca478fe065f01d7f8285f7c173ccfcfccristy     (ping_exclude_iCCP == MagickFalse || ping_exclude_zCCP == MagickFalse))
9789c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp    {
9790c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      ResetImageProfileIterator(image);
9791c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      for (name=GetNextImageProfile(image); name != (const char *) NULL; )
97923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9793c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        profile=GetImageProfile(image,name);
97940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9795c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        if (profile != (StringInfo *) NULL)
9796c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          {
9797c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp#ifdef PNG_WRITE_iCCP_SUPPORTED
9798c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            if ((LocaleCompare(name,"ICC") == 0) ||
9799c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                (LocaleCompare(name,"ICM") == 0))
980026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             {
9801c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp
9802c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               if (ping_exclude_iCCP == MagickFalse)
9803c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 {
9804c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                       png_set_iCCP(ping,ping_info,(const png_charp) name,0,
9805e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#if (PNG_LIBPNG_VER < 10500)
9806c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_charp) GetStringInfoDatum(profile),
9807e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#else
9808e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp                         (png_const_bytep) GetStringInfoDatum(profile),
9809e4017e34baec05ee0a45800ed8efb2ff6d5c9f5aglennrp#endif
9810c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                         (png_uint_32) GetStringInfoLength(profile));
9811c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 }
981226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             }
98130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9814c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            else
98153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
9816c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              if (ping_exclude_zCCP == MagickFalse)
9817c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                {
9818cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  Magick_png_write_raw_profile(image_info,ping,ping_info,
9819c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (unsigned char *) name,(unsigned char *) name,
9820c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    GetStringInfoDatum(profile),
9821c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                    (png_uint_32) GetStringInfoLength(profile));
9822c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                }
9823c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          }
98240b206f5daa453dc1035db5890cabc899736dc2d0glennrp
9825c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp          if (logging != MagickFalse)
9826c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9827c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp              "  Setting up text chunk with %s profile",name);
98280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9829c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        name=GetNextImageProfile(image);
9830c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp      }
98313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
98323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
98333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_sRGB_SUPPORTED)
98343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((mng_info->have_write_global_srgb == 0) &&
98353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((image->rendering_intent != UndefinedIntent) ||
98363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (image->colorspace == sRGBColorspace)))
98373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
983826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_sRGB == MagickFalse)
983926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
984026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          /*
984126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            Note image rendering intent.
984226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          */
984326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if (logging != MagickFalse)
984426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
984526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                "  Setting up sRGB chunk");
98460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
984726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) png_set_sRGB(ping,ping_info,(
9848cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            Magick_RenderingIntent_to_PNG_RenderingIntent(
9849cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              image->rendering_intent)));
98504054bfbdca478fe065f01d7f8285f7c173ccfcfccristy
98514054bfbdca478fe065f01d7f8285f7c173ccfcfccristy          if (ping_exclude_gAMA == MagickFalse)
98524054bfbdca478fe065f01d7f8285f7c173ccfcfccristy            png_set_gAMA(ping,ping_info,0.45455);
985326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
98543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
985526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
98565af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if ((!mng_info->write_mng) || (!png_get_valid(ping,ping_info,PNG_INFO_sRGB)))
98573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
98583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
98592cc891a179d622dde7bbb8854138851e828bc6eaglennrp      if (ping_exclude_gAMA == MagickFalse &&
98602cc891a179d622dde7bbb8854138851e828bc6eaglennrp          (ping_exclude_sRGB == MagickFalse ||
986126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (image->gamma < .45 || image->gamma > .46)))
986226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      {
98633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->have_write_global_gama == 0) && (image->gamma != 0.0))
98643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
98653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
98663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Note image gamma.
98673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
98683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
98693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
98703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
98713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Setting up gAMA chunk");
98723b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
98733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          png_set_gAMA(ping,ping_info,image->gamma);
98743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
987526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      }
98762b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
987726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_exclude_cHRM == MagickFalse)
98783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
987926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          if ((mng_info->have_write_global_chrm == 0) &&
988026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (image->chromaticity.red_primary.x != 0.0))
988126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
988226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              /*
988326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                Note image chromaticity.
988426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
988526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              */
988626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               PrimaryInfo
988726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 bp,
988826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 gp,
988926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 rp,
989026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 wp;
989126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
989226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               wp=image->chromaticity.white_point;
989326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               rp=image->chromaticity.red_primary;
989426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               gp=image->chromaticity.green_primary;
989526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               bp=image->chromaticity.blue_primary;
989626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
989726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               if (logging != MagickFalse)
989826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
989926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   "  Setting up cHRM chunk");
990026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
990126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp               png_set_cHRM(ping,ping_info,wp.x,wp.y,rp.x,rp.y,gp.x,gp.y,
990226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                   bp.x,bp.y);
990326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           }
990426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
99053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9906dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
99075af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  ping_interlace_method=image_info->interlace != NoInterlace;
99083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng)
99103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    png_set_sig_bytes(ping,8);
99113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Bail out if cannot meet defined PNG:bit-depth or PNG:color-type */
99133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9914d6bf1617e99df0272b231855a933a74e99b6578fglennrp  if (mng_info->write_png_colortype != 0)
99153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY)
99178d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
99183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
99195af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           ping_color_type = PNG_COLOR_TYPE_RGB;
99202b013e4b9b602533eff410e61c3683fb2a3ab913glennrp
99215af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp           if (ping_bit_depth < 8)
99225af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             ping_bit_depth=8;
99233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
99240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
99253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_GRAY_ALPHA)
99268d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       if (ping_have_color != MagickFalse)
99275af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         ping_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
99283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99300e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  if (ping_need_colortype_warning != MagickFalse ||
99310e8ea19baa0666ccfe869d19116372f60fe9230fglennrp     ((mng_info->write_png_depth &&
99325af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     (int) mng_info->write_png_depth != ping_bit_depth) ||
99333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (mng_info->write_png_colortype &&
99345af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp     ((int) mng_info->write_png_colortype-1 != ping_color_type &&
9935991e92a91acb9e432cd6c05843e4f6a57643e29dglennrp      mng_info->write_png_colortype != 7 &&
99360e8ea19baa0666ccfe869d19116372f60fe9230fglennrp      !(mng_info->write_png_colortype == 5 && ping_color_type == 0)))))
99373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
99393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
99400e8ea19baa0666ccfe869d19116372f60fe9230fglennrp          if (ping_need_colortype_warning != MagickFalse)
99410e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            {
99420e8ea19baa0666ccfe869d19116372f60fe9230fglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99430e8ea19baa0666ccfe869d19116372f60fe9230fglennrp                 "  Image has transparency but tRNS chunk was excluded");
99440e8ea19baa0666ccfe869d19116372f60fe9230fglennrp            }
99450e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
99463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_depth)
99473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
99483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:bit-depth=%u, Computed depth=%u",
99503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth,
99515af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_bit_depth);
99523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
99530e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
99543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype)
99553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
99563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  "  Defined PNG:color-type=%u, Computed color type=%u",
99583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_colortype-1,
99595af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp                  ping_color_type);
99603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
99613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
99620e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
99633bd2e411d0f07c705a40c2c73ce7eda3f1f03e0cglennrp      png_warning(ping,
99643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "Cannot write image with defined PNG:bit-depth or PNG:color-type.");
99653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
996758e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp  if (image_matte != MagickFalse && image->matte == MagickFalse)
99683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
99693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Add an opaque matte channel */
99703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->matte = MagickTrue;
99713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageOpacity(image,0);
99720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
9973b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      if (logging != MagickFalse)
9974b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9975b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp          "  Added an opaque matte channel");
99763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
99773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99780e319739731741c52a6303723e0c8678a0df5579glennrp  if (number_transparent != 0 || number_semitransparent != 0)
9979e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    {
9980991d11dd9c33e65872778b81aff1347cd2878154glennrp      if (ping_color_type < 4)
9981c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        {
9982991d11dd9c33e65872778b81aff1347cd2878154glennrp           ping_have_tRNS=MagickTrue;
9983c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp           if (logging != MagickFalse)
9984c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
9985c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp               "  Setting ping_have_tRNS=MagickTrue.");
9986c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp        }
9987e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp    }
9988e9c26dc68fb7cff87adcf2677968737acc9d3d2cglennrp
99893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
99903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
99913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG header chunks");
99923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
99935af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  png_set_IHDR(ping,ping_info,ping_width,ping_height,
99945af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_bit_depth,ping_color_type,
99955af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_interlace_method,ping_compression_method,
99965af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp               ping_filter_method);
99975af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
999839992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_color_type == 3 && ping_have_PLTE != MagickFalse)
999939992b4dd9b12ef752d55b8e402c069698851f72glennrp    {
10000f09bdedccf9ca10bc002a946227df3367cb58d14glennrp      png_set_PLTE(ping,ping_info,palette,number_colors);
100010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
100023b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
1000339992b4dd9b12ef752d55b8e402c069698851f72glennrp        {
100048640fb5e9b1094f35f8beab436f81661b8a99448glennrp          for (i=0; i< (ssize_t) number_colors; i++)
100050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          {
10006d6bf1617e99df0272b231855a933a74e99b6578fglennrp            if (i < ping_num_trans)
100070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10008d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d), tRNS[%d] = (%d)",
10009d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
100100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
100110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
100120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue,
10013d6bf1617e99df0272b231855a933a74e99b6578fglennrp                      (int) i,
100140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) ping_trans_alpha[i]);
100150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             else
100160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10017d6bf1617e99df0272b231855a933a74e99b6578fglennrp                "     PLTE[%d] = (%d,%d,%d)",
100180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) i,
100190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].red,
100200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].green,
100210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                      (int) palette[i].blue);
100220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           }
1002339992b4dd9b12ef752d55b8e402c069698851f72glennrp         }
1002439992b4dd9b12ef752d55b8e402c069698851f72glennrp    }
1002539992b4dd9b12ef752d55b8e402c069698851f72glennrp
1002626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_bKGD == MagickFalse)
1002726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1002826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_bKGD != MagickFalse)
10029c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp        {
1003026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_bKGD(ping,ping_info,&ping_background);
10031c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp          if (logging)
10032c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            {
10033c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10034c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "    Setting up bKGD chunk");
10035c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10036c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      background color = (%d,%d,%d)",
10037c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.red,
10038c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.green,
10039c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.blue);
10040c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10041c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                   "      index = %d, gray=%d",
10042c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.index,
10043c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp                        (int) ping_background.gray);
10044c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp            }
10045c6c391a2036b6e500b986d1635c50b9a89ea331dglennrp         }
1004626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
10047991d11dd9c33e65872778b81aff1347cd2878154glennrp
1004826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_pHYs == MagickFalse)
10049dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1005026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (ping_have_pHYs != MagickFalse)
1005126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1005226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          png_set_pHYs(ping,ping_info,
1005326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_x_resolution,
1005426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_y_resolution,
1005526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             ping_pHYs_unit_type);
10056823b55c200d7fc1818ab539b036a9c24feaecda8glennrp
10057823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          if (logging)
10058823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            {
10059823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10060823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "    Setting up pHYs chunk");
10061823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10062823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      x_resolution=%lu",
10063823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_x_resolution);
10064823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10065823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      y_resolution=%lu",
10066823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_y_resolution);
10067823b55c200d7fc1818ab539b036a9c24feaecda8glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10068823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   "      unit_type=%lu",
10069823b55c200d7fc1818ab539b036a9c24feaecda8glennrp                   (unsigned long) ping_pHYs_unit_type);
10070823b55c200d7fc1818ab539b036a9c24feaecda8glennrp            }
1007126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10072dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10073dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10074dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#if defined(PNG_oFFs_SUPPORTED)
100754f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp  if (ping_exclude_oFFs == MagickFalse)
10076dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    {
1007726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      if (image->page.x || image->page.y)
1007826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1007926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
1008026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp              (png_int_32) image->page.y, 0);
10081dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
1008226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp           if (logging != MagickFalse)
1008326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1008426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 "    Setting up oFFs chunk with x=%d, y=%d, units=0",
1008526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp                 (int) image->page.x, (int) image->page.y);
1008626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
10087dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp    }
10088dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp#endif
10089dfd7080ae717c8ddb013b59958f2d0790f5e3145glennrp
10090da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (mng_info->need_blob != MagickFalse)
10091da8f3a7bfddac2680a3069a490db541e7944edafglennrp  {
10092da8f3a7bfddac2680a3069a490db541e7944edafglennrp    if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) ==
10093da8f3a7bfddac2680a3069a490db541e7944edafglennrp       MagickFalse)
10094da8f3a7bfddac2680a3069a490db541e7944edafglennrp       png_error(ping,"WriteBlob Failed");
10095da8f3a7bfddac2680a3069a490db541e7944edafglennrp
10096da8f3a7bfddac2680a3069a490db541e7944edafglennrp     ping_have_blob=MagickTrue;
10097da8f3a7bfddac2680a3069a490db541e7944edafglennrp  }
10098da8f3a7bfddac2680a3069a490db541e7944edafglennrp
100993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info_before_PLTE(ping, ping_info);
10100991d11dd9c33e65872778b81aff1347cd2878154glennrp
1010139992b4dd9b12ef752d55b8e402c069698851f72glennrp  if (ping_have_tRNS != MagickFalse && ping_color_type < 4)
10102991d11dd9c33e65872778b81aff1347cd2878154glennrp    {
101033b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp      if (logging != MagickFalse)
101040fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
101050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
101060fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp              "  Calling png_set_tRNS with num_trans=%d",ping_num_trans);
101070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        }
10108991d11dd9c33e65872778b81aff1347cd2878154glennrp
101090fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if (ping_color_type == 3)
101100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         (void) png_set_tRNS(ping, ping_info,
101110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_trans_alpha,
101120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                ping_num_trans,
101130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                NULL);
10114991d11dd9c33e65872778b81aff1347cd2878154glennrp
101150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      else
101160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp        {
101170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp           (void) png_set_tRNS(ping, ping_info,
101180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  NULL,
101190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  0,
101200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                  &ping_trans_color);
101210fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
101223b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp           if (logging != MagickFalse)
101230fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             {
101240fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10125c8cbc5d89664c67b8a8f3f4619fc7ce19ea654bcglennrp                 "     tRNS color   =(%d,%d,%d)",
101260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.red,
101270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.green,
101280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp                       (int) ping_trans_color.blue);
101290fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp             }
101300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp         }
101310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp    }
10132991d11dd9c33e65872778b81aff1347cd2878154glennrp
101333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any png-chunk-b profiles */
10134cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-b",logging);
10135da8f3a7bfddac2680a3069a490db541e7944edafglennrp
101363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_info(ping,ping_info);
10137991d11dd9c33e65872778b81aff1347cd2878154glennrp
101383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-m profiles */
10139cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-m",logging);
101403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1014126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  if (ping_exclude_vpAg == MagickFalse)
101423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
101434f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp      if ((image->page.width != 0 && image->page.width != image->columns) ||
101444f25bd0f2f7f8673457c20de30664b5982b57b7cglennrp          (image->page.height != 0 && image->page.height != image->rows))
1014526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
1014626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          unsigned char
1014726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            chunk[14];
1014826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1014926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
1015026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGType(chunk,mng_vpAg);
1015103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_vpAg,9L);
1015226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+4,(png_uint_32) image->page.width);
1015326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          PNGLong(chunk+8,(png_uint_32) image->page.height);
1015426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          chunk[12]=0;   /* unit = pixels */
1015526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlob(image,13,chunk);
1015626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
1015726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
101583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if (PNG_LIBPNG_VER == 10206)
101619c1eb0729653219b9da9037e044501a6dce79d10glennrp    /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
101623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define PNG_HAVE_IDAT               0x04
101639c1eb0729653219b9da9037e044501a6dce79d10glennrp    ping->mode |= PNG_HAVE_IDAT;
101643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#undef PNG_HAVE_IDAT
101653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
101663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_set_packing(ping);
101683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
101693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate memory.
101703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
101713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  rowbytes=image->columns;
10172b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp  if (image_depth > 8)
10173b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp    rowbytes*=2;
101747202c101b42be63076be56386f79429bb2f39784cristy  switch (ping_color_type)
101753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10176b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGB:
101773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=3;
10178b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
101790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10180b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_GRAY_ALPHA:
10181b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        rowbytes*=2;
10182b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
101830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10184b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      case PNG_COLOR_TYPE_RGBA:
101853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        rowbytes*=4;
10186b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
101870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10188b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      default:
10189b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        break;
101903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
101913b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp
101923b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp  if (logging != MagickFalse)
101933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
10194b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10195b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Writing PNG image data");
101960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10197b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10198e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Allocating %.20g bytes of memory for pixels",(double) rowbytes);
101993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10200cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) AcquireQuantumMemory(rowbytes,
10201cf002022280cc4dedb2748ad6f415aac1d44f530glennrp    sizeof(*ping_pixels));
102020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10203cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  if (ping_pixels == (unsigned char *) NULL)
102043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
102073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image scanlines.
102083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
102095af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp  if (setjmp(png_jmpbuf(ping)))
102103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
102123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        PNG write failed.
102133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
102143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_DEBUG
102153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image_info->verbose)
102163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) printf("PNG write has failed.\n");
102173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
102183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      png_destroy_write_struct(&ping,&ping_info);
102193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (quantum_info != (QuantumInfo *) NULL)
102203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        quantum_info=DestroyQuantumInfo(quantum_info);
10221cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      if (ping_pixels != (unsigned char *) NULL)
10222cf002022280cc4dedb2748ad6f415aac1d44f530glennrp        ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
102233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
10224cf002022280cc4dedb2748ad6f415aac1d44f530glennrp      UnlockSemaphoreInfo(ping_semaphore);
102253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
10226da8f3a7bfddac2680a3069a490db541e7944edafglennrp      if (ping_have_blob != MagickFalse)
10227b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp          (void) CloseBlob(image);
10228b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image_info=DestroyImageInfo(image_info);
10229b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp      image=DestroyImage(image);
102303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(MagickFalse);
102313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
10232ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  quantum_info=AcquireQuantumInfo(image_info,image);
10233ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy  if (quantum_info == (QuantumInfo *) NULL)
10234ed5525230af20461366cdc5b8bbe0f7f9b166c44cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
102353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->format=UndefinedQuantumFormat;
102363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info->depth=image_depth;
102373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  num_passes=png_set_interlace_handling(ping);
102388bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
102393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((!mng_info->write_png8 && !mng_info->write_png24 &&
102408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       !mng_info->write_png32) &&
102418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp       (mng_info->IsPalette ||
102423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (image_info->type == BilevelType)) &&
102438d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       image_matte == MagickFalse &&
102448d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp       ping_have_non_bw == MagickFalse)
102453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
102468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp      /* Palette, Bilevel, or Opaque Monochrome */
102474c08aed51c5899665ade97263692328eea4af106cristy      register const Quantum
102483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
102490fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      quantum_info->depth=8;
102513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (pass=0; pass < num_passes; pass++)
102523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
102533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
102543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Convert PseudoClass image to a PNG monochrome image.
102553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
10256bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (y=0; y < (ssize_t) image->rows; y++)
102573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
10258d71e86a4e57997f1aad16e85b542612b1d2f9b6eglennrp          if (logging != MagickFalse && y == 0)
102593b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
102603b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                 "    Writing row of pixels (0)");
10261a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp
102623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
102630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102644c08aed51c5899665ade97263692328eea4af106cristy          if (p == (const Quantum *) NULL)
102653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
102660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->IsPalette)
102683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
102694c08aed51c5899665ade97263692328eea4af106cristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
10270cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,GrayQuantum,ping_pixels,&image->exception);
102713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (mng_info->write_png_colortype-1 == PNG_COLOR_TYPE_PALETTE &&
102723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth &&
102733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->write_png_depth != old_bit_depth)
102743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
102753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  /* Undo pixel scaling */
10276bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                  for (i=0; i < (ssize_t) image->columns; i++)
10277cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                     *(ping_pixels+i)=(unsigned char) (*(ping_pixels+i)
102783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     >> (8-old_bit_depth));
102793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
102803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
102810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
102833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
102844c08aed51c5899665ade97263692328eea4af106cristy              (void) ExportQuantumPixels(image,(CacheView *) NULL,
10285cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                quantum_info,RedQuantum,ping_pixels,&image->exception);
102863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
102870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (mng_info->write_png_colortype-1 != PNG_COLOR_TYPE_PALETTE)
10289bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy            for (i=0; i < (ssize_t) image->columns; i++)
10290cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               *(ping_pixels+i)=(unsigned char) ((*(ping_pixels+i) > 127) ?
102913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      255 : 0);
102920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
102933b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp          if (logging != MagickFalse && y == 0)
10294b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10295b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                "    Writing row of pixels (1)");
102960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10297cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          png_write_row(ping,ping_pixels);
102983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
102993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->previous == (Image *) NULL)
103003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
103013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            status=SetImageProgress(image,LoadImageTag,pass,num_passes);
103023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (status == MagickFalse)
103033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
103043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
103053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
103063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
103070fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp  else   /* Not Palette, Bilevel, or Opaque Monochrome */
103093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
103100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp      if ((!mng_info->write_png8 && !mng_info->write_png24 &&
103113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         !mng_info->write_png32) &&
1031258e017631f66141a6e36ddbe03a54f6e3ee3a253glennrp         (image_matte != MagickFalse ||
103135af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp         (ping_bit_depth >= MAGICKCORE_QUANTUM_DEPTH)) &&
103148d579660c9b96b7a3f3292fc6c518f8b6ca44d50glennrp         (mng_info->IsPalette) && ping_have_color == MagickFalse)
103153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
103164c08aed51c5899665ade97263692328eea4af106cristy          register const Quantum
103178bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
103180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103198bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
103203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
103218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10322bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (y=0; y < (ssize_t) image->rows; y++)
103233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
103243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
103252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103264c08aed51c5899665ade97263692328eea4af106cristy            if (p == (const Quantum *) NULL)
103273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
103282cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103295af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp            if (ping_color_type == PNG_COLOR_TYPE_GRAY)
103303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
103318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (mng_info->IsPalette)
103324c08aed51c5899665ade97263692328eea4af106cristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
10333cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,GrayQuantum,ping_pixels,&image->exception);
103342cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                else
103364c08aed51c5899665ade97263692328eea4af106cristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
10337cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RedQuantum,ping_pixels,&image->exception);
103382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
103408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                       "    Writing GRAY PNG pixels (2)");
103423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
103432cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103448bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            else /* PNG_COLOR_TYPE_GRAY_ALPHA */
10345b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
103463b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10347b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103488bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                         "    Writing GRAY_ALPHA PNG pixels (2)");
103492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103504c08aed51c5899665ade97263692328eea4af106cristy                (void) ExportQuantumPixels(image,(CacheView *) NULL,
10351cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                  quantum_info,GrayAlphaQuantum,ping_pixels,&image->exception);
10352b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
103532cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103543b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp            if (logging != MagickFalse && y == 0)
10355b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
103568bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  "    Writing row of pixels (2)");
103572cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10358cf002022280cc4dedb2748ad6f415aac1d44f530glennrp            png_write_row(ping,ping_pixels);
103593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
103602cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103618bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          if (image->previous == (Image *) NULL)
103628bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
103638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              status=SetImageProgress(image,LoadImageTag,pass,num_passes);
103648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if (status == MagickFalse)
103658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                break;
103668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
103678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          }
103688bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp        }
103690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
103713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
103724c08aed51c5899665ade97263692328eea4af106cristy          register const Quantum
103738bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            *p;
103740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
103758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          for (pass=0; pass < num_passes; pass++)
103763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
103778bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if ((image_depth > 8) || (mng_info->write_png24 ||
103788bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
103798bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette)))
103808bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
103818bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
10382b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              {
103838bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
103848bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                   &image->exception);
103852cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103864c08aed51c5899665ade97263692328eea4af106cristy                if (p == (const Quantum *) NULL)
103878bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
103882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103898bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
103908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
103918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (image->storage_class == DirectClass)
103924c08aed51c5899665ade97263692328eea4af106cristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
10393cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,RedQuantum,ping_pixels,&image->exception);
103942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
103958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    else
103964c08aed51c5899665ade97263692328eea4af106cristy                      (void) ExportQuantumPixels(image,(CacheView *) NULL,
10397cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                        quantum_info,GrayQuantum,ping_pixels,&image->exception);
103988bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
103992cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104008bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
104018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
104024c08aed51c5899665ade97263692328eea4af106cristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10403cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                      quantum_info,GrayAlphaQuantum,ping_pixels,
104048bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      &image->exception);
104052cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104068bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
104078bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104088bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "    Writing GRAY_ALPHA PNG pixels (3)");
104098bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
104102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104118bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (image_matte != MagickFalse)
104124c08aed51c5899665ade97263692328eea4af106cristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
10413cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBAQuantum,ping_pixels,&image->exception);
104142cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104158bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
104164c08aed51c5899665ade97263692328eea4af106cristy                  (void) ExportQuantumPixels(image,(CacheView *) NULL,
10417cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                    quantum_info,RGBQuantum,ping_pixels,&image->exception);
104182cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104193b51f0e7f4f7cce3e7466784c8b4e5dac9f55741glennrp                if (logging != MagickFalse && y == 0)
10420b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104218bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "    Writing row of pixels (3)");
104222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10423cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
10424b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp              }
104258bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
104262cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104278bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp          else
104288bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            /* not ((image_depth > 8) || (mng_info->write_png24 ||
104298bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                mng_info->write_png32 ||
104308bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                (!mng_info->write_png8 && !mng_info->IsPalette))) */
104318bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            {
104328bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              if ((ping_color_type != PNG_COLOR_TYPE_GRAY) &&
104338bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (ping_color_type != PNG_COLOR_TYPE_GRAY_ALPHA))
104348bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                {
104358bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  if (logging != MagickFalse)
104368bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104378bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      "  pass %d, Image Is not GRAY or GRAY_ALPHA",pass);
104382cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104398bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  quantum_info->depth=8;
104408bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  image_depth=8;
104418bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                }
104422cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104438bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              for (y=0; y < (ssize_t) image->rows; y++)
104448640fb5e9b1094f35f8beab436f81661b8a99448glennrp              {
104458bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (logging != MagickFalse && y == 0)
104468bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104478bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    "  pass %d, Image Is RGB, 16-bit GRAY, or GRAY_ALPHA",pass);
104482cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10449770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                p=GetVirtualPixels(image,0,y,image->columns,1,
10450770d193edfaf07ccf8d1947f6c3c6ee45fa65971glennrp                   &image->exception);
104512cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104524c08aed51c5899665ade97263692328eea4af106cristy                if (p == (const Quantum *) NULL)
104538bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
104542cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104558bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (ping_color_type == PNG_COLOR_TYPE_GRAY)
1045644757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  {
104574bf89731a90c6e03598950223e19e7be7b95d630glennrp                    quantum_info->depth=image->depth;
104584bf89731a90c6e03598950223e19e7be7b95d630glennrp
104594c08aed51c5899665ade97263692328eea4af106cristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10460cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                       quantum_info,GrayQuantum,ping_pixels,&image->exception);
1046144757ab033a4bc1f272fb26c9a46325ca01a5482glennrp                  }
104622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104638bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else if (ping_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
104648bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
104658bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                    if (logging != MagickFalse && y == 0)
104668bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104678bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                           "  Writing GRAY_ALPHA PNG pixels (4)");
104682cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104694c08aed51c5899665ade97263692328eea4af106cristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
10470cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                         quantum_info,GrayAlphaQuantum,ping_pixels,
10471d6bf1617e99df0272b231855a933a74e99b6578fglennrp                         &image->exception);
104728bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
104732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104748bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                else
104758bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  {
104764c08aed51c5899665ade97263692328eea4af106cristy                    (void) ExportQuantumPixels(image,(CacheView *) NULL,
104775eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      quantum_info,IndexQuantum,ping_pixels,&image->exception);
104782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104795eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    if (logging != MagickFalse && y <= 2)
104805eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    {
104815eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104821a7d6dbd296698a7cddbc625896987bf674c0cc4glennrp                          "  Writing row of non-gray pixels (4)");
104835eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp
104845eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
104855eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          "  ping_pixels[0]=%d,ping_pixels[1]=%d",
104865eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                          (int)ping_pixels[0],(int)ping_pixels[1]);
104875eae76090b1e30c1e546508dd1d17711ddd3fcc0glennrp                    }
104888bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  }
10489cf002022280cc4dedb2748ad6f415aac1d44f530glennrp                png_write_row(ping,ping_pixels);
104908bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              }
104918bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            }
104922cc891a179d622dde7bbb8854138851e828bc6eaglennrp
104938bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp            if (image->previous == (Image *) NULL)
104948bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp              {
104958bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                status=SetImageProgress(image,LoadImageTag,pass,num_passes);
104968bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                if (status == MagickFalse)
104978bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp                  break;
104988640fb5e9b1094f35f8beab436f81661b8a99448glennrp              }
104993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
105003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105018bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp    }
105028bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
10503b32b90a7e1ee2275333589072c496b5f69e17feccristy  if (quantum_info != (QuantumInfo *) NULL)
10504b32b90a7e1ee2275333589072c496b5f69e17feccristy    quantum_info=DestroyQuantumInfo(quantum_info);
105053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
105063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
105073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
105083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10509b4a1341a4d06abe5f603ad9052b6ddc1a667dcd5glennrp        "  Wrote PNG image data");
105100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10512e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Width: %.20g",(double) ping_width);
105130fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10515e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Height: %.20g",(double) ping_height);
105160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_depth)
105183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:bit-depth: %d",mng_info->write_png_depth);
105213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105245af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG bit-depth written: %d",ping_bit_depth);
105250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->write_png_colortype)
105273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
105283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "    Defined PNG:color-type: %d",mng_info->write_png_colortype-1);
105303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
105310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105335af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG color-type written: %d",ping_color_type);
105340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
105353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
105365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp        "    PNG Interlace method: %d",ping_interlace_method);
105373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
105383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
10539a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    Generate text chunks after IDAT.
105403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
10541823b55c200d7fc1818ab539b036a9c24feaecda8glennrp  if (ping_exclude_tEXt == MagickFalse || ping_exclude_zTXt == MagickFalse)
105423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
1054326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    ResetImagePropertyIterator(image);
1054426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    property=GetNextImageProperty(image);
1054526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    while (property != (const char *) NULL)
1054626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    {
1054726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      png_textp
1054826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        text;
105492cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1055026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      value=GetImageProperty(image,property);
10551a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10552a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      /* Don't write any "png:" properties; those are just for "identify" */
10553a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(property,"png:",4) != 0 &&
10554a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10555a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress density and units if we wrote a pHYs chunk */
10556a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_pHYs != MagickFalse      ||
10557823b55c200d7fc1818ab539b036a9c24feaecda8glennrp          LocaleCompare(property,"density") != 0 ||
10558a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleCompare(property,"units") != 0) &&
10559a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
10560a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          /* Suppress the IM-generated Date:create and Date:modify */
10561a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          (ping_exclude_date == MagickFalse      ||
10562a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          LocaleNCompare(property, "Date:",5) != 0))
1056326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        {
10564c70af4ac292f8db9a1ab488318912894d412cb8cglennrp        if (value != (const char *) NULL)
10565c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          {
10566c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text=(png_textp) png_malloc(ping,(png_uint_32) sizeof(png_text));
10567c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].key=(char *) property;
10568c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text=(char *) value;
10569c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            text[0].text_length=strlen(value);
105702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10571c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (ping_exclude_tEXt != MagickFalse)
10572c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_zTXt;
105732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10574c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else if (ping_exclude_zTXt != MagickFalse)
10575c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=PNG_TEXT_COMPRESSION_NONE;
105762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10577c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            else
1057826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            {
10579c70af4ac292f8db9a1ab488318912894d412cb8cglennrp               text[0].compression=image_info->compression == NoCompression ||
10580c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 (image_info->compression == UndefinedCompression &&
10581c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 text[0].text_length < 128) ? PNG_TEXT_COMPRESSION_NONE :
10582c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                 PNG_TEXT_COMPRESSION_zTXt ;
1058326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp            }
105842cc891a179d622dde7bbb8854138851e828bc6eaglennrp
10585c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            if (logging != MagickFalse)
10586c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              {
10587c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10588c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "  Setting up text chunk");
10589c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10590c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10591c70af4ac292f8db9a1ab488318912894d412cb8cglennrp                  "    keyword: %s",text[0].key);
10592c70af4ac292f8db9a1ab488318912894d412cb8cglennrp              }
10593c70af4ac292f8db9a1ab488318912894d412cb8cglennrp
10594c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_set_text(ping,ping_info,text,1);
10595c70af4ac292f8db9a1ab488318912894d412cb8cglennrp            png_free(ping,text);
10596c70af4ac292f8db9a1ab488318912894d412cb8cglennrp          }
1059726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp        }
1059826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      property=GetNextImageProperty(image);
1059926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    }
106003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
106013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* write any PNG-chunk-e profiles */
10603cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"PNG-chunk-e",logging);
106043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
106063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Writing PNG end info");
106080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_write_end(ping,ping_info);
106100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->need_fram && (int) image->dispose == BackgroundDispose)
106123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
106133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.x || mng_info->page.y ||
106145af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_width != mng_info->page.width) ||
106155af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp          (ping_height != mng_info->page.height))
106163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
106173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          unsigned char
106183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            chunk[32];
106193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
106213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write FRAM 4 with clipping boundaries followed by FRAM 1.
106223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
106233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,27L);  /* data length=27 */
106243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_FRAM);
1062503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_FRAM,27L);
106263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[4]=4;
106273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[5]=0;  /* frame name separator (no name) */
106283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[6]=1;  /* flag for changing delay, for next frame only */
106293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[7]=0;  /* flag for changing frame timeout */
106303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[8]=1;  /* flag for changing frame clipping for next frame */
106313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[9]=0;  /* flag for changing frame sync_id */
106323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+10,(png_uint_32) (0L)); /* temporary 0 delay */
106333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[14]=0; /* clipping boundaries delta type */
106343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+15,(png_uint_32) (mng_info->page.x)); /* left cb */
106353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+19,
106365af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.x + ping_width));
106373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+23,(png_uint_32) (mng_info->page.y)); /* top cb */
106383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGLong(chunk+27,
106395af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp             (png_uint_32) (mng_info->page.y + ping_height));
106403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,31,chunk);
106413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,31));
106423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->old_framing_mode=4;
106433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->framing_mode=1;
106443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
106450fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
106473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->framing_mode=3;
106483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
106493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng && !mng_info->need_fram &&
106503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((int) image->dispose == 3))
10651c70af4ac292f8db9a1ab488318912894d412cb8cglennrp     (void) ThrowMagickException(&image->exception,GetMagickModule(),
106523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       CoderError,"Cannot convert GIF with disposal method 3 to MNG-LC",
10653c70af4ac292f8db9a1ab488318912894d412cb8cglennrp       "`%s'",image->filename);
106540fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
106563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Free PNG resources.
106573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
106585af765f10ae9ac5aae02c0b7c213e22a43c0672dglennrp
106593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  png_destroy_write_struct(&ping,&ping_info);
106603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10661cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  ping_pixels=(unsigned char *) RelinquishMagickMemory(ping_pixels);
106623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_SETJMP_NOT_THREAD_SAFE)
10664cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  UnlockSemaphoreInfo(ping_semaphore);
106653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
106663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10667da8f3a7bfddac2680a3069a490db541e7944edafglennrp  if (ping_have_blob != MagickFalse)
10668b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp     (void) CloseBlob(image);
10669b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
10670b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image_info=DestroyImageInfo(image_info);
10671b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  image=DestroyImage(image);
10672b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
10673b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  /* Store bit depth actually written */
10674b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[0]=(char) ping_bit_depth;
10675b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  s[1]='\0';
10676b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
10677b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  (void) SetImageProperty(IMimage,"png:bit-depth-written",s);
10678b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp
106793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
106803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
106813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOnePNGImage()");
106820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
106833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
106843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*  End write one PNG image */
106853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
106863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
106873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
106883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P N G I m a g e                                                 %
106933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
106963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
106983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePNGImage() writes a Portable Network Graphics (PNG) or
106993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Multiple-image Network Graphics (MNG) image file.
107003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  MNG support written by Glenn Randers-Pehrson, glennrp@image...
107023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePNGImage method is:
107043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107051e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WritePNGImage(const ImageInfo *image_info,
107061e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
107073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
107093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
107113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
107133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107141e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
107151e178e70fb3c956f9fc1e30c3ba863e882666465cristy%
107163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Returns MagickTrue on success, MagickFalse on failure.
107173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Communicating with the PNG encoder:
107193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  While the datastream written is always in PNG format and normally would
107213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  be given the "png" file extension, this method also writes the following
107223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pseudo-formats which are subsets of PNG:
107233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107245a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%    o PNG8:    An 8-bit indexed PNG datastream is written.  If the image has
107255a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               a depth greater than 8, the depth is reduced. If transparency
107263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               is present, the tRNS chunk must only have values 0 and 255
107273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               (i.e., transparency is binary: fully opaque or fully
107285a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent).  If other values are present they will be
107295a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               50%-thresholded to binary transparency.  If more than 256
10730e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               colors are present, they will be quantized to the 4-4-4-1,
10731130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               3-3-3-1, or 3-3-2-1 palette.  The underlying RGB color
10732130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               of any resulting fully-transparent pixels is changed to
10733130fc4535f884af19ec188e80a5cdcd89b0052e0glennrp%               the image's background color.
10734e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%
10735e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               If you want better quantization or dithering of the colors
10736e9637cb863ebc78027c145832eaf0b3a62bf2a56glennrp%               or alpha than that, you need to do it before calling the
107375a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG encoder. The pixels contain 8-bit indices even if
107385a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               they could be represented with 1, 2, or 4 bits.  Grayscale
107393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               images will be written as indexed PNG files even though the
107405a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               PNG grayscale type might be slightly more efficient.  Please
107415a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               note that writing to the PNG8 format may result in loss
107425a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               of color and alpha data.
107433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG24:   An 8-bit per sample RGB PNG datastream is written.  The tRNS
107453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               chunk can be present to convey binary transparency by naming
107465a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               one of the colors as transparent.  The only loss incurred
107475a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               is reduction of sample depth to 8.  If the image has more
107485a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               than one transparent color, has semitransparent pixels, or
107495a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               has an opaque pixel with the same RGB components as the
107505a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               transparent color, an image is not written.
107513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o PNG32:   An 8-bit per sample RGBA PNG is written.  Partial
107533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               transparency is permitted, i.e., the alpha sample for
107543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               each pixel can have any value from 0 to 255. The alpha
107550fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%               channel is present even if the image is fully opaque.
107565a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               The only loss in data is the reduction of the sample depth
107575a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%               to 8.
107583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o -define: For more precise control of the PNG output, you can use the
107603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Image options "png:bit-depth" and "png:color-type".  These
107613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               can be set from the commandline with "-define" and also
10762bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               from the application programming interfaces.  The options
10763bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               are case-independent and are converted to lowercase before
10764bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%               being passed to this encoder.
107653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:color-type can be 0, 2, 3, 4, or 6.
107673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 0 (Grayscale), png:bit-depth can
107693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, 8, or 16.
107703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 2 (RGB), png:bit-depth can
107723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 8 or 16.
107733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 3 (Indexed), png:bit-depth can
107753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               be 1, 2, 4, or 8.  This refers to the number of bits
107763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               used to store the index.  The color samples always have
107773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               bit-depth 8 in indexed PNG files.
107783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               When png:color-type is 4 (Gray-Matte) or 6 (RGB-Matte),
107803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               png:bit-depth can be 8 or 16.
107813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107825a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  If the image cannot be written without loss with the requested bit-depth
107835a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  and color-type, a PNG file will not be written, and the encoder will
107845a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  return MagickFalse.
107855a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%
107863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Since image encoders should not be responsible for the "heavy lifting",
107873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the user should make sure that ImageMagick has already reduced the
107883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  image depth and number of colors and limit transparency to binary
107895a39f3714559b4d9c08beb391ce4326354bb0f0cglennrp%  transparency prior to attempting to write the image with depth, color,
1079054dc0694601d2c51ec50c76e3fd90d9ff704df9bglennrp%  or transparency limitations.
107913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Note that another definition, "png:bit-depth-written" exists, but it
107933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  is not intended for external use.  It is only used internally by the
107943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PNG encoder to inform the JNG encoder of the depth of the alpha channel.
107953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
107963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  It is possible to request that the PNG encoder write previously-formatted
107973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ancillary chunks in the output PNG file, using the "-profile" commandline
107983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  option as shown below or by setting the profile via a programming
107993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  interface:
108003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%     -profile PNG-chunk-x:<file>
108023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  where x is a location flag and <file> is a file containing the chunk
108043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  name in the first 4 bytes, then a colon (":"), followed by the chunk data.
10805bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  This encoder will compute the chunk length and CRC, so those must not
10806bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  be included in the file.
108073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  "x" can be "b" (before PLTE), "m" (middle, i.e., between PLTE and IDAT),
108093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  or "e" (end, i.e., after IDAT).  If you want to write multiple chunks
108103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  of the same type, then add a short unique string after the "x" to prevent
10811bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%  subsequent profiles from overwriting the preceding ones, e.g.,
108123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10813bb8a733a352d1143bf6e823471ccce72aee8189fglennrp%     -profile PNG-chunk-b01:file01 -profile PNG-chunk-b02:file02
108143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108153241bd0c43e56612fc7aa006a0d30333dacbb51aglennrp%  As of version 6.6.6 the following optimizations are always done:
108160fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
10817d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  32-bit depth is reduced to 16.
108180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  16-bit depth is reduced to 8 if all pixels contain samples whose
108190fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%      high byte and low byte are identical.
108200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Palette is sorted to remove unused entries and to put a
10821cf002022280cc4dedb2748ad6f415aac1d44f530glennrp%      transparent color first, if BUILD_PNG_PALETTE is defined.
108220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%   o  Opaque matte channel is removed when writing an indexed PNG.
10823d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Grayscale images are reduced to 1, 2, or 4 bit depth if
10824d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      this can be done without loss and a larger bit depth N was not
10825d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      requested via the "-define PNG:bit-depth=N" option.
10826d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  If matte channel is present but only one transparent color is
10827d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      present, RGB+tRNS is written instead of RGBA
10828d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%   o  Opaque matte channel is removed (or added, if color-type 4 or 6
10829d6afd54fac7c96376ea623fb7ab6c3e398cb7064glennrp%      was requested when converting an opaque image).
108300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp%
108313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
108333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,
108341e178e70fb3c956f9fc1e30c3ba863e882666465cristy  Image *image,ExceptionInfo *exception)
108353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
108363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1083721f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    excluding,
1083821f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    logging,
1083921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
108403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
108413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
108433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
108443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
108463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *value;
108473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
1084921f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    i,
108505c7cf4e469a4dad7e277783749155932252c52dfglennrp    source;
108515c7cf4e469a4dad7e277783749155932252c52dfglennrp
108523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
108543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
108563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
108573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
108583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
108593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
10860fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WritePNGImage()");
108613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
108633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1086573bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
108660fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
108683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
108690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
108713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
108723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
108733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
108743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
10875a521b2fe1f4c8b8ab9412bd6ef23b6736b90e43dglennrp  mng_info->equal_backgrounds=MagickTrue;
108763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
108773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* See if user has requested a specific PNG subformat */
108793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
108813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
108823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
108833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png8)
108853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108869c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 3 */ 4;
108879c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
108889c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
108893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
108903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
108913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png24)
108923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
108939c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 2 */ 3;
108949c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
108959c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
108960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
108979c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
108989c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
108990fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109009c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
109019c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
109020fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109039c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
109043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_png32)
109073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109089c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_colortype = /* 6 */  7;
109099c1eb0729653219b9da9037e044501a6dce79d10glennrp      mng_info->write_png_depth = 8;
109109c1eb0729653219b9da9037e044501a6dce79d10glennrp      image->depth = 8;
109110fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109129c1eb0729653219b9da9037e044501a6dce79d10glennrp      if (image->matte == MagickTrue)
109139c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorMatteType);
109140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109159c1eb0729653219b9da9037e044501a6dce79d10glennrp      else
109169c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) SetImageType(image,TrueColorType);
109170fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109189c1eb0729653219b9da9037e044501a6dce79d10glennrp      (void) SyncImage(image);
109193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:bit-depth");
109228bb3a02a0021145f36ed1057d3153c74abdcabaeglennrp
109233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
109243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"1") == 0)
109269c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 1;
109270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
109299c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 2;
109300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
109329c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 4;
109330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"8") == 0)
109359c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 8;
109360fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"16") == 0)
109389c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_depth = 16;
109390fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10940bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10941bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10942bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10943bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:bit-depth",
10944bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10945bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
109463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
109479c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10948bb8a733a352d1143bf6e823471ccce72aee8189fglennrp          "  png:bit-depth=%d was defined.\n",mng_info->write_png_depth);
109493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109500fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  value=GetImageOption(image_info,"png:color-type");
109520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (value != (char *) NULL)
109543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
109553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* We must store colortype+1 because 0 is a valid colortype */
109563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(value,"0") == 0)
109579c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 1;
109580fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"2") == 0)
109609c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 3;
109610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"3") == 0)
109639c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 4;
109640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"4") == 0)
109669c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 5;
109670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
109683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else if (LocaleCompare(value,"6") == 0)
109699c1eb0729653219b9da9037e044501a6dce79d10glennrp        mng_info->write_png_colortype = 7;
109700fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
10971bb8a733a352d1143bf6e823471ccce72aee8189fglennrp      else
10972bb8a733a352d1143bf6e823471ccce72aee8189fglennrp        (void) ThrowMagickException(&image->exception,
10973bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             GetMagickModule(),CoderWarning,
10974bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "ignoring invalid defined png:color-type",
10975bb8a733a352d1143bf6e823471ccce72aee8189fglennrp             "=%s",value);
10976bb8a733a352d1143bf6e823471ccce72aee8189fglennrp
109773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
109789c1eb0729653219b9da9037e044501a6dce79d10glennrp        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
10979d6bf1617e99df0272b231855a933a74e99b6578fglennrp          "  png:color-type=%d was defined.\n",mng_info->write_png_colortype-1);
109803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
109813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
109820e8ea19baa0666ccfe869d19116372f60fe9230fglennrp  /* Check for chunks to be excluded:
109830e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
109840dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * The default is to not exclude any known chunks except for any
109850e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * listed in the "unused_chunks" array, above.
109860e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
109870e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Chunks can be listed for exclusion via a "PNG:exclude-chunk"
109880e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * define (in the image properties or in the image artifacts)
109890e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or via a mng_info member.  For convenience, in addition
109900e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * to or instead of a comma-separated list of chunks, the
109910e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string can be simply "all" or "none".
109920e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
109930e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The exclude-chunk define takes priority over the mng_info.
109940e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
109950e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * A "PNG:include-chunk" define takes  priority over both the
109960e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * mng_info and the "PNG:exclude-chunk" define.  Like the
109970e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * "exclude-chunk" string, it can define "all" or "none" as
109980dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * well as a comma-separated list.  Chunks that are unknown to
109990dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * ImageMagick are always excluded, regardless of their "copy-safe"
110000dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * status according to the PNG specification, and even if they
110010dff56c31fb2f5daa9744018ca533e387c246afcglennrp   * appear in the "include-chunk" list.
110020e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
110030e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * Finally, all chunks listed in the "unused_chunks" array are
110040e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * automatically excluded, regardless of the other instructions
110050e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * or lack thereof.
110060e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
110070e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * if you exclude sRGB but not gAMA (recommended), then sRGB chunk
110080e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * will not be written and the gAMA chunk will only be written if it
110090e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is not between .45 and .46, or approximately (1.0/2.2).
110100e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
110110e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * If you exclude tRNS and the image has transparency, the colortype
110120e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * is forced to be 4 or 6 (GRAY_ALPHA or RGB_ALPHA).
110130e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   *
110140e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   * The -strip option causes StripImage() to set the png:include-chunk
11015104f206c40efbb0a0eeba846672009345423e969glennrp   * artifact to "none,trns,gama".
110160e8ea19baa0666ccfe869d19116372f60fe9230fglennrp   */
110170e8ea19baa0666ccfe869d19116372f60fe9230fglennrp
1101826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_bKGD=MagickFalse;
1101926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_cHRM=MagickFalse;
11020a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp  mng_info->ping_exclude_date=MagickFalse;
1102126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_EXIF=MagickFalse; /* hex-encoded EXIF in zTXt */
1102226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_gAMA=MagickFalse;
1102326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_iCCP=MagickFalse;
1102426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  /* mng_info->ping_exclude_iTXt=MagickFalse; */
1102526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_oFFs=MagickFalse;
1102626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_pHYs=MagickFalse;
1102726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_sRGB=MagickFalse;
1102826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_tEXt=MagickFalse;
11029a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp  mng_info->ping_exclude_tRNS=MagickFalse;
1103026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_vpAg=MagickFalse;
1103126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zCCP=MagickFalse; /* hex-encoded iCCP in zTXt */
1103226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  mng_info->ping_exclude_zTXt=MagickFalse;
1103326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
110348d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  mng_info->ping_preserve_colormap=MagickFalse;
110358d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
110368d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  value=GetImageArtifact(image,"png:preserve-colormap");
110378d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value == NULL)
110388d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     value=GetImageOption(image_info,"png:preserve-colormap");
110398d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp  if (value != NULL)
110408d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp     mng_info->ping_preserve_colormap=MagickTrue;
110418d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp
110421868258559ddf946fa73ef72dd43507b32623705glennrp  /* Thes compression-level, compression-strategy, and compression-filter
110431868258559ddf946fa73ef72dd43507b32623705glennrp   * defines take precedence over values from the -quality option.
110441868258559ddf946fa73ef72dd43507b32623705glennrp   */
110451868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-level");
110461868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
110471868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-level");
110481868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
110491868258559ddf946fa73ef72dd43507b32623705glennrp  {
110501868258559ddf946fa73ef72dd43507b32623705glennrp      /* We have to add 1 to everything because 0 is a valid input,
110511868258559ddf946fa73ef72dd43507b32623705glennrp       * and we want to use 0 (the default) to mean undefined.
110521868258559ddf946fa73ef72dd43507b32623705glennrp       */
110531868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
110541868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 1;
110551868258559ddf946fa73ef72dd43507b32623705glennrp
110561868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"1") == 0)
110571868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 2;
110581868258559ddf946fa73ef72dd43507b32623705glennrp
110591868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
110601868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 3;
110611868258559ddf946fa73ef72dd43507b32623705glennrp
110621868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
110631868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 4;
110641868258559ddf946fa73ef72dd43507b32623705glennrp
110651868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
110661868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 5;
110671868258559ddf946fa73ef72dd43507b32623705glennrp
110681868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
110691868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 6;
110701868258559ddf946fa73ef72dd43507b32623705glennrp
110711868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"6") == 0)
110721868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 7;
110731868258559ddf946fa73ef72dd43507b32623705glennrp
110741868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"7") == 0)
110751868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 8;
110761868258559ddf946fa73ef72dd43507b32623705glennrp
110771868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"8") == 0)
110781868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 9;
110791868258559ddf946fa73ef72dd43507b32623705glennrp
110801868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"9") == 0)
110811868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_level = 10;
110821868258559ddf946fa73ef72dd43507b32623705glennrp
110831868258559ddf946fa73ef72dd43507b32623705glennrp      else
110841868258559ddf946fa73ef72dd43507b32623705glennrp        (void) ThrowMagickException(&image->exception,
110851868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
110861868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-level",
110871868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
110881868258559ddf946fa73ef72dd43507b32623705glennrp    }
110891868258559ddf946fa73ef72dd43507b32623705glennrp
110901868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-strategy");
110911868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
110921868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-strategy");
110931868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
110941868258559ddf946fa73ef72dd43507b32623705glennrp  {
110951868258559ddf946fa73ef72dd43507b32623705glennrp
110961868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
110971868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
110981868258559ddf946fa73ef72dd43507b32623705glennrp
110991868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"1") == 0)
111001868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FILTERED+1;
111011868258559ddf946fa73ef72dd43507b32623705glennrp
111021868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
111031868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_HUFFMAN_ONLY+1;
111041868258559ddf946fa73ef72dd43507b32623705glennrp
111051868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
1110698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_RLE  /* Z_RLE was added to zlib-1.2.0 */
111071868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_RLE+1;
1110898c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1110998c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1111098c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
111111868258559ddf946fa73ef72dd43507b32623705glennrp
111121868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
1111398c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#ifdef Z_FIXED  /* Z_FIXED was added to zlib-1.2.2.2 */
111141868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_strategy = Z_FIXED+1;
1111598c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#else
1111698c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp        mng_info->write_png_compression_strategy = Z_DEFAULT_STRATEGY+1;
1111798c07ad97d2b2c4571ec3b58241df30d43ba51d0glennrp#endif
111181868258559ddf946fa73ef72dd43507b32623705glennrp
111191868258559ddf946fa73ef72dd43507b32623705glennrp      else
111201868258559ddf946fa73ef72dd43507b32623705glennrp        (void) ThrowMagickException(&image->exception,
111211868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
111221868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-strategy",
111231868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
111241868258559ddf946fa73ef72dd43507b32623705glennrp    }
111251868258559ddf946fa73ef72dd43507b32623705glennrp
111261868258559ddf946fa73ef72dd43507b32623705glennrp  value=GetImageArtifact(image,"png:compression-filter");
111271868258559ddf946fa73ef72dd43507b32623705glennrp  if (value == NULL)
111281868258559ddf946fa73ef72dd43507b32623705glennrp     value=GetImageOption(image_info,"png:compression-filter");
111291868258559ddf946fa73ef72dd43507b32623705glennrp  if (value != NULL)
111301868258559ddf946fa73ef72dd43507b32623705glennrp  {
111311868258559ddf946fa73ef72dd43507b32623705glennrp
111321868258559ddf946fa73ef72dd43507b32623705glennrp      /* To do: combinations of filters allowed by libpng
111331868258559ddf946fa73ef72dd43507b32623705glennrp       * masks 0x08 through 0xf8
111341868258559ddf946fa73ef72dd43507b32623705glennrp       *
111351868258559ddf946fa73ef72dd43507b32623705glennrp       * Implement this as a comma-separated list of 0,1,2,3,4,5
111361868258559ddf946fa73ef72dd43507b32623705glennrp       * where 5 is a special case meaning PNG_ALL_FILTERS.
111371868258559ddf946fa73ef72dd43507b32623705glennrp       */
111381868258559ddf946fa73ef72dd43507b32623705glennrp
111391868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"0") == 0)
111401868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 1;
111411868258559ddf946fa73ef72dd43507b32623705glennrp
111421868258559ddf946fa73ef72dd43507b32623705glennrp      if (LocaleCompare(value,"1") == 0)
111431868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 2;
111441868258559ddf946fa73ef72dd43507b32623705glennrp
111451868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"2") == 0)
111461868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 3;
111471868258559ddf946fa73ef72dd43507b32623705glennrp
111481868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"3") == 0)
111491868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 4;
111501868258559ddf946fa73ef72dd43507b32623705glennrp
111511868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"4") == 0)
111521868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 5;
111531868258559ddf946fa73ef72dd43507b32623705glennrp
111541868258559ddf946fa73ef72dd43507b32623705glennrp      else if (LocaleCompare(value,"5") == 0)
111551868258559ddf946fa73ef72dd43507b32623705glennrp        mng_info->write_png_compression_filter = 6;
111561868258559ddf946fa73ef72dd43507b32623705glennrp
111571868258559ddf946fa73ef72dd43507b32623705glennrp      else
111581868258559ddf946fa73ef72dd43507b32623705glennrp        (void) ThrowMagickException(&image->exception,
111591868258559ddf946fa73ef72dd43507b32623705glennrp             GetMagickModule(),CoderWarning,
111601868258559ddf946fa73ef72dd43507b32623705glennrp             "ignoring invalid defined png:compression-filter",
111611868258559ddf946fa73ef72dd43507b32623705glennrp             "=%s",value);
111621868258559ddf946fa73ef72dd43507b32623705glennrp    }
111631868258559ddf946fa73ef72dd43507b32623705glennrp
1116403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  excluding=MagickFalse;
1116503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
111665c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
111675c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
111685c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11169acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
111705c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:exclude-chunk");
11171acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11172acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11173acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:exclude-chunks");
11174acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
111755c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11176acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
111775c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:exclude-chunk");
1117826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11179acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11180acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:exclude-chunks");
11181acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11182acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1118303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1118403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1118526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1118603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1118703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1118826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1118903812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1119026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1119103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
111922cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
111932cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
111942cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111952cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image artifacts.\n", value);
111962cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
111972cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
111982cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:exclude-chunk=%s found in image properties.\n", value);
111992cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1120003812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1120103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1120203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1120303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1120403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1120503812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1120603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1120703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1120803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
1120903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
11210a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
1121103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
1121203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
1121303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
1121403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickTrue; */
1121503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
1121603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
1121703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickTrue;
1121803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
11219a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
1122003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
1122103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
1122203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
1122303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        i--;
1122403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
112252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1122603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1122703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1122803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
1122903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
11230a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
1123103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
1123203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
1123303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
1123403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        /* mng_info->ping_exclude_iTXt=MagickFalse; */
1123503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
1123603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
1123703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_sRGB=MagickFalse;
1123803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
11239a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
1124003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
1124103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
1124203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
1124303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
112442cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1124503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1124603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickTrue;
112472cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1124803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1124903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickTrue;
112502cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11251a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11252a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickTrue;
11253a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1125403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1125503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickTrue;
112562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1125703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1125803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
112592cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1126003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1126103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickTrue;
112622cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1126303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1126403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1126503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickTrue;
1126603812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
112672cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1126803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1126903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickTrue;
112702cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1127103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1127203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickTrue;
112732cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1127403812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1127503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickTrue;
112762cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11277a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11278a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickTrue;
112792cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1128003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1128103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickTrue;
112822cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11283a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11284a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickTrue;
11285a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1128603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1128703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickTrue;
112882cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1128903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1129003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickTrue;
112912cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1129203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1129303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickTrue;
112942cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1129503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11296ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1129726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1129826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
112995c7cf4e469a4dad7e277783749155932252c52dfglennrp  for (source=0; source<1; source++)
113005c7cf4e469a4dad7e277783749155932252c52dfglennrp  {
113015c7cf4e469a4dad7e277783749155932252c52dfglennrp    if (source==0)
11302acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
113035c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageArtifact(image,"png:include-chunk");
11304acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
11305acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11306acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageArtifact(image,"png:include-chunks");
11307acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
113085c7cf4e469a4dad7e277783749155932252c52dfglennrp    else
11309acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      {
113105c7cf4e469a4dad7e277783749155932252c52dfglennrp       value=GetImageOption(image_info,"png:include-chunk");
1131126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11312acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp       if (value == NULL)
11313acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp         value=GetImageOption(image_info,"png:include-chunks");
11314acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp      }
11315acba004f7fac1660554dfefd2a078ead5ac8ee14glennrp
1131603812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (value != NULL)
1131703812ae402fb53d548f0e1d7d14720768f803c2dglennrp    {
1131803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    size_t
1131903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      last;
1132026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1132103812ae402fb53d548f0e1d7d14720768f803c2dglennrp    excluding=MagickTrue;
1132226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1132303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    if (logging != MagickFalse)
113242cc891a179d622dde7bbb8854138851e828bc6eaglennrp      {
113252cc891a179d622dde7bbb8854138851e828bc6eaglennrp        if (source == 0)
113262cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113272cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image artifacts.\n", value);
113282cc891a179d622dde7bbb8854138851e828bc6eaglennrp        else
113292cc891a179d622dde7bbb8854138851e828bc6eaglennrp           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
113302cc891a179d622dde7bbb8854138851e828bc6eaglennrp              "  png:include-chunk=%s found in image properties.\n", value);
113312cc891a179d622dde7bbb8854138851e828bc6eaglennrp      }
1133203812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1133303812ae402fb53d548f0e1d7d14720768f803c2dglennrp    last=strlen(value);
1133403812ae402fb53d548f0e1d7d14720768f803c2dglennrp
1133503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    for (i=0; i<(int) last; i+=5)
1133603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      {
1133703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"all",3) == 0)
1133803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1133903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickFalse;
1134003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickFalse;
11341a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickFalse;
1134203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickFalse;
1134303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickFalse;
1134403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickFalse;
1134503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickFalse; */
1134603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickFalse;
1134703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickFalse;
1134803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickFalse;
1134903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickFalse;
11350a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickFalse;
1135103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickFalse;
1135203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickFalse;
1135303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickFalse;
1135403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          i--;
1135503812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
113562cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1135703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"none",4) == 0)
1135803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        {
1135903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_bKGD=MagickTrue;
1136003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_cHRM=MagickTrue;
11361a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          mng_info->ping_exclude_date=MagickTrue;
1136203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_EXIF=MagickTrue;
1136303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_gAMA=MagickTrue;
1136403812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_iCCP=MagickTrue;
1136503812ae402fb53d548f0e1d7d14720768f803c2dglennrp          /* mng_info->ping_exclude_iTXt=MagickTrue; */
1136603812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_oFFs=MagickTrue;
1136703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_pHYs=MagickTrue;
1136803812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_sRGB=MagickTrue;
1136903812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_tEXt=MagickTrue;
11370a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          mng_info->ping_exclude_tRNS=MagickTrue;
1137103812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_vpAg=MagickTrue;
1137203812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zCCP=MagickTrue;
1137303812ae402fb53d548f0e1d7d14720768f803c2dglennrp          mng_info->ping_exclude_zTXt=MagickTrue;
1137403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        }
113752cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1137603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"bkgd",4) == 0)
1137703812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_bKGD=MagickFalse;
113782cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1137903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"chrm",4) == 0)
1138003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_cHRM=MagickFalse;
113812cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11382a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      if (LocaleNCompare(value+i,"date",4) == 0)
11383a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp        mng_info->ping_exclude_date=MagickFalse;
11384a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp
1138503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"exif",4) == 0)
1138603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_EXIF=MagickFalse;
113872cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1138803812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1138903812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
113902cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1139103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"iccp",4) == 0)
1139203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iCCP=MagickFalse;
113932cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1139403812ae402fb53d548f0e1d7d14720768f803c2dglennrp    /*
1139503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"itxt",4) == 0)
1139603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_iTXt=MagickFalse;
1139703812ae402fb53d548f0e1d7d14720768f803c2dglennrp     */
113982cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1139903812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"gama",4) == 0)
1140003812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_gAMA=MagickFalse;
114012cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1140203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"offs",4) == 0)
1140303812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_oFFs=MagickFalse;
114042cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1140503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"phys",4) == 0)
1140603812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_pHYs=MagickFalse;
114072cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11408a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"srgb",4) == 0)
11409a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_sRGB=MagickFalse;
114102cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1141103812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"text",4) == 0)
1141203812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_tEXt=MagickFalse;
114132cc891a179d622dde7bbb8854138851e828bc6eaglennrp
11414a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      if (LocaleNCompare(value+i,"trns",4) == 0)
11415a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp        mng_info->ping_exclude_tRNS=MagickFalse;
11416a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp
1141703812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"vpag",4) == 0)
1141803812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_vpAg=MagickFalse;
114192cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1142003812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"zccp",4) == 0)
1142103812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zCCP=MagickFalse;
114222cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1142303812ae402fb53d548f0e1d7d14720768f803c2dglennrp      if (LocaleNCompare(value+i,"ztxt",4) == 0)
1142403812ae402fb53d548f0e1d7d14720768f803c2dglennrp        mng_info->ping_exclude_zTXt=MagickFalse;
114252cc891a179d622dde7bbb8854138851e828bc6eaglennrp
1142603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      }
11427ce91ed5de546373b90d60e2efd118e76692dc416glennrp    }
1142826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1142926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
1143003812ae402fb53d548f0e1d7d14720768f803c2dglennrp  if (excluding != MagickFalse && logging != MagickFalse)
1143126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  {
1143226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1143326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      "  Chunks to be excluded from the output PNG:");
1143426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_bKGD != MagickFalse)
1143526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1143626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    bKGD");
1143726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_cHRM != MagickFalse)
1143826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1143926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    cHRM");
11440a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp    if (mng_info->ping_exclude_date != MagickFalse)
11441a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11442a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp          "    date");
1144326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_EXIF != MagickFalse)
1144426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1144526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    EXIF");
1144626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_gAMA != MagickFalse)
1144726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1144826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    gAMA");
1144926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iCCP != MagickFalse)
1145026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1145126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iCCP");
1145226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp/*
1145326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_iTXt != MagickFalse)
1145426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1145526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    iTXt");
1145626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp*/
1145726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_oFFs != MagickFalse)
1145826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1145926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    oFFs");
1146026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_pHYs != MagickFalse)
1146126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1146226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    pHYs");
1146326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_sRGB != MagickFalse)
1146426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1146526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    sRGB");
1146626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_tEXt != MagickFalse)
1146726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1146826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    tEXt");
11469a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp    if (mng_info->ping_exclude_tRNS != MagickFalse)
11470a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11471a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp          "    tRNS");
1147226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_vpAg != MagickFalse)
1147326f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1147426f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    vpAg");
1147526f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zCCP != MagickFalse)
1147626f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1147726f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zCCP");
1147826f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp    if (mng_info->ping_exclude_zTXt != MagickFalse)
1147926f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1148026f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp          "    zTXt");
1148126f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp  }
1148226f379198a1c94db76f302873c7f1f2e8d5ec6a0glennrp
11483b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  mng_info->need_blob = MagickTrue;
114843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11485b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp  status=WriteOnePNGImage(mng_info,image_info,image);
114863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
114880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
114903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WritePNGImage()");
114910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
114923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
114933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
114943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
114963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
114973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* Write one JNG image */
114983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteOneJNGImage(MngInfo *mng_info,
114993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   const ImageInfo *image_info,Image *image)
115003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
115013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
115023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image;
115033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ImageInfo
115053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *jpeg_image_info;
115063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1150803812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
115093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
115103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
115123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    length;
115133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
115153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *blob,
115163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[80],
115173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
115183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned int
115203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_compression_method,
115213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_alpha_sample_depth,
115223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type,
115233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    transparent;
115243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11525bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
115263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_quality;
115273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  logging=LogMagickEvent(CoderEvent,GetMagickModule(),
11529fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp    "  Enter WriteOneJNGImage()");
115303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) NULL;
115323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=(Image *) NULL;
115333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) NULL;
115343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
115363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  transparent=image_info->type==GrayscaleMatteType ||
115373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->type==TrueColorMatteType;
115383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_color_type=10;
115393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_sample_depth=0;
115403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_quality=image_info->quality == 0UL ? 75UL : image_info->quality;
115413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jng_alpha_compression_method=0;
115423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->matte != MagickFalse)
115443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
115453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* if any pixels are transparent */
115463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      transparent=MagickTrue;
115473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->compression==JPEGCompression)
115483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jng_alpha_compression_method=8;
115493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
115523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
11553bd5a96cd2b69f218f85a7adc306296a736f91a56cristy      ChannelType
11554bd5a96cd2b69f218f85a7adc306296a736f91a56cristy        channel_mask;
11555bd5a96cd2b69f218f85a7adc306296a736f91a56cristy
115563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jng_color_type=14;
115570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Create JPEG blob, image, and image_info */
115593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
115603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115614c08aed51c5899665ade97263692328eea4af106cristy          "  Creating jpeg_image_info for alpha.");
115620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
115640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image_info == (ImageInfo *) NULL)
115663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
115670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (logging != MagickFalse)
115693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
115703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "  Creating jpeg_image.");
115710fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
115730fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jpeg_image == (Image *) NULL)
115753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
115760fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
11578bd5a96cd2b69f218f85a7adc306296a736f91a56cristy      channel_mask=SetPixelChannelMask(jpeg_image,AlphaChannel);
115793139dc2f5df8d442e308b381992a0f8579e061e4cristy      status=SeparateImage(jpeg_image);
11580bd5a96cd2b69f218f85a7adc306296a736f91a56cristy      (void) SetPixelChannelMap(jpeg_image,channel_mask);
115813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image->matte=MagickFalse;
115820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_quality >= 1000)
115843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality/1000;
115850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
115873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        jpeg_image_info->quality=jng_quality;
115880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
115893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info->type=GrayscaleType;
115903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageType(jpeg_image,GrayscaleType);
115913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) AcquireUniqueFilename(jpeg_image->filename);
115923b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy      (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,
115933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "%s",jpeg_image->filename);
115943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
115953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* To do: check bit depth of PNG alpha channel */
115973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Check if image is grayscale. */
115993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->type != TrueColorMatteType && image_info->type !=
116003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    TrueColorType && ImageIsGray(image))
116013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jng_color_type-=2;
116023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
116043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
116063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
116073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          const char
116083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *value;
116093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116104c08aed51c5899665ade97263692328eea4af106cristy          /* Encode alpha as a grayscale PNG blob */
116113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
116123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
116133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
116143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating PNG blob.");
116163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          length=0;
116173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"PNG",MaxTextExtent);
116193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"PNG",MaxTextExtent);
116203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
116213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
116233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
116243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Retrieve sample depth used */
116263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          value=GetImageProperty(jpeg_image,"png:bit-depth-written");
116273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (value != (char *) NULL)
116283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            jng_alpha_sample_depth= (unsigned int) value[0];
116293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
116303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
116313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
116324c08aed51c5899665ade97263692328eea4af106cristy          /* Encode alpha as a grayscale JPEG blob */
116333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
116353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &image->exception);
116363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
116383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
116393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jpeg_image_info->interlace=NoInterlace;
116403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
116413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              "  Creating blob.");
116433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,
11644f2faecf9facdbbb14fcba373365f9f691a9658e0cristy           &image->exception);
116453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          jng_alpha_sample_depth=8;
116460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
116483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11649e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Successfully read jpeg_image into a blob, length=%.20g.",
11650e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              (double) length);
116513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
116533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Destroy JPEG image and image_info */
116543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image=DestroyImage(jpeg_image);
116553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
116563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      jpeg_image_info=DestroyImageInfo(jpeg_image_info);
116573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
116583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JHDR chunk */
116603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,16L);  /* chunk data length=16 */
116613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JHDR);
1166203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JHDR,16L);
116634e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+4,(png_uint_32) image->columns);
116644e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy  PNGLong(chunk+8,(png_uint_32) image->rows);
116653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[12]=jng_color_type;
116663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[13]=8;  /* sample depth */
116673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[14]=8; /*jng_image_compression_method */
116683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[15]=(unsigned char) (image_info->interlace == NoInterlace ? 0 : 8);
116693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[16]=jng_alpha_sample_depth;
116703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[17]=jng_alpha_compression_method;
116713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[18]=0; /*jng_alpha_filter_method */
116723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  chunk[19]=0; /*jng_alpha_interlace_method */
116733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,20,chunk);
116743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
116753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
116763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
116773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11678f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG width:%15lu",(unsigned long) image->columns);
116790fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11681f2faecf9facdbbb14fcba373365f9f691a9658e0cristy        "    JNG height:%14lu",(unsigned long) image->rows);
116820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG color type:%10d",jng_color_type);
116850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG sample depth:%8d",8);
116880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG compression:%9d",8);
116910fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG interlace:%11d",0);
116940fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha depth:%9d",jng_alpha_sample_depth);
116970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
116983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
116993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha compression:%3d",jng_alpha_compression_method);
117000fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
117023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha filter:%8d",0);
117030fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
117053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    JNG alpha interlace:%5d",0);
117063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp  /* Write any JNG-chunk-b profiles */
11709cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-b",logging);
117103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
117123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     Write leading ancillary chunks
117133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
117143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
117163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
117173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
117183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Write JNG bKGD chunk
117193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
117203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    unsigned char
117223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blue,
117233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      green,
117243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      red;
117253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11726bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    ssize_t
117273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes;
117283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (jng_color_type == 8 || jng_color_type == 12)
117303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=6L;
117313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
117323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      num_bytes=10L;
11733bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    (void) WriteBlobMSBULong(image,(size_t) (num_bytes-4L));
117343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    PNGType(chunk,mng_bKGD);
1173503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    LogPNGChunk(logging,mng_bKGD,(size_t) (num_bytes-4L));
117363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    red=ScaleQuantumToChar(image->background_color.red);
117373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    green=ScaleQuantumToChar(image->background_color.green);
117383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blue=ScaleQuantumToChar(image->background_color.blue);
117393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+4)=0;
117403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+5)=red;
117413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+6)=0;
117423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+7)=green;
117433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+8)=0;
117443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *(chunk+9)=blue;
117453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlob(image,(size_t) num_bytes,chunk);
117463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) num_bytes));
117473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
117483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->colorspace == sRGBColorspace || image->rendering_intent))
117503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
117513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
117523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write JNG sRGB chunk
117533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
117543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,1L);
117553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_sRGB);
1175603812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_sRGB,1L);
117570fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->rendering_intent != UndefinedIntent)
11759e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
11760cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
11761e610a071534e448c46460a5aa39ede33bf56b329glennrp          (image->rendering_intent));
117620fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
11764e610a071534e448c46460a5aa39ede33bf56b329glennrp        chunk[4]=(unsigned char)
11765cf002022280cc4dedb2748ad6f415aac1d44f530glennrp          Magick_RenderingIntent_to_PNG_RenderingIntent(
11766e610a071534e448c46460a5aa39ede33bf56b329glennrp          (PerceptualIntent));
117670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,5,chunk);
117693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
117703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
117713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
117723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
117733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->gamma != 0.0)
117743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
117753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
117763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG gAMA chunk
117773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
117783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,4L);
117793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_gAMA);
1178003812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_gAMA,4L);
1178135ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
117823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,8,chunk);
117833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
117843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
117850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
117863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((mng_info->equal_chrms == MagickFalse) &&
117873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (image->chromaticity.red_primary.x != 0.0))
117883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
117893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PrimaryInfo
117903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            primary;
117913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
117923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
117933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write JNG cHRM chunk
117943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
117953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,32L);
117963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_cHRM);
1179703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_cHRM,32L);
117983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.white_point;
1179935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1180035ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
118013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.red_primary;
1180235ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1180335ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
118043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.green_primary;
1180535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1180635ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
118073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          primary=image->chromaticity.blue_primary;
1180835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1180935ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
118103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,36,chunk);
118113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
118123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
118133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118140fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->x_resolution && image->y_resolution && !mng_info->equal_physs)
118163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
118183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG pHYs chunk
118193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
118203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
118213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_pHYs);
1182203812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_pHYs,9L);
118233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image->units == PixelsPerInchResolution)
118243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
1182535ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+4,(png_uint_32)
118263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->x_resolution*100.0/2.54+0.5));
118270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1182835ef824baa82511126ff0072ae30eee0da9c05a3cristy          PNGLong(chunk+8,(png_uint_32)
118293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (image->y_resolution*100.0/2.54+0.5));
118300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          chunk[12]=1;
118323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
118330fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
118353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
118363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (image->units == PixelsPerCentimeterResolution)
118373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1183835ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32)
118393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->x_resolution*100.0+0.5));
118400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1184135ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32)
118423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (image->y_resolution*100.0+0.5));
118430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=1;
118453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
118460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
118473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
118483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
1184935ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1185035ef824baa82511126ff0072ae30eee0da9c05a3cristy              PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
118513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              chunk[12]=0;
118523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
118533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
118543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
118553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
118563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
118593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
118613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         Write JNG oFFs chunk
118623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
118633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,9L);
118643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_oFFs);
1186503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_oFFs,9L);
11866bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+4,(ssize_t) (image->page.x));
11867bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      PNGsLong(chunk+8,(ssize_t) (image->page.y));
118683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      chunk[12]=0;
118693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,13,chunk);
118703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
118713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info->write_mng == 0 && (image->page.width || image->page.height))
118733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,9L);  /* data length=8 */
118753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGType(chunk,mng_vpAg);
1187603812ae402fb53d548f0e1d7d14720768f803c2dglennrp       LogPNGChunk(logging,mng_vpAg,9L);
118773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+4,(png_uint_32) image->page.width);
118783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       PNGLong(chunk+8,(png_uint_32) image->page.height);
118793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       chunk[12]=0;   /* unit = pixels */
118803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlob(image,13,chunk);
118813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
118823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
118833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (transparent)
118863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
118873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (jng_alpha_compression_method==0)
118883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
11889bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          register ssize_t
118903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            i;
118913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11892bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          ssize_t
118933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len;
118943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
118953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write IDAT chunk header */
118963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
118973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11898e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write IDAT chunks from blob, length=%.20g.",(double)
11899f2faecf9facdbbb14fcba373365f9f691a9658e0cristy              length);
119003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Copy IDAT chunks */
119023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          len=0;
119033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=blob+8;
11904bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          for (i=8; i<(ssize_t) length; i+=len+12)
119053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
119063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            len=(*p<<24)|((*(p+1))<<16)|((*(p+2))<<8)|(*(p+3));
119073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=4;
119080fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*(p)==73 && *(p+1)==68 && *(p+2)==65 && *(p+3)==84) /* IDAT */
119103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
119113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /* Found an IDAT chunk. */
11912bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                (void) WriteBlobMSBULong(image,(size_t) len);
1191303812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_IDAT,(size_t) len);
119143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,(size_t) len+4,p);
119153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,
119163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    crc32(0,p,(uInt) len+4));
119173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
119180fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
119203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
119213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (logging != MagickFalse)
119223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11923e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    "    Skipping %c%c%c%c chunk, length=%.20g.",
11924e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                    *(p),*(p+1),*(p+2),*(p+3),(double) len);
119253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
119263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=(8+len);
119273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
119283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
119303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
119313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAA chunk header */
119323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (logging != MagickFalse)
119333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11934e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              "  Write JDAA chunk, length=%.20g.",(double) length);
11935bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy          (void) WriteBlobMSBULong(image,(size_t) length);
119363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          PNGType(chunk,mng_JDAA);
1193703812ae402fb53d548f0e1d7d14720768f803c2dglennrp          LogPNGChunk(logging,mng_JDAA,length);
119383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /* Write JDAT chunk(s) data */
119393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,4,chunk);
119403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,length,blob);
119413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,
119423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (uInt) length));
119433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
119443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      blob=(unsigned char *) RelinquishMagickMemory(blob);
119453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Encode image as a JPEG blob */
119483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image_info.");
119513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=(ImageInfo *) CloneImageInfo(image_info);
119523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image_info == (ImageInfo *) NULL)
119533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
119543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating jpeg_image.");
119583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=CloneImage(image,0,0,MagickTrue,&image->exception);
119603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jpeg_image == (Image *) NULL)
119613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
119623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
119633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) AcquireUniqueFilename(jpeg_image->filename);
119653b6fd2ec2d9f69f9404445dba0aff5bac02e685ccristy  (void) FormatLocaleString(jpeg_image_info->filename,MaxTextExtent,"%s",
119663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image->filename);
119673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(jpeg_image_info,jpeg_image,WriteBinaryBlobMode,
119693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    &image->exception);
119703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11973e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      "  Created jpeg_image, %.20g x %.20g.",(double) jpeg_image->columns,
11974e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy      (double) jpeg_image->rows);
119753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (jng_color_type == 8 || jng_color_type == 12)
119773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    jpeg_image_info->type=GrayscaleType;
119780fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info->quality=jng_quality % 1000;
119803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image_info->magick,"JPEG",MaxTextExtent);
119813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(jpeg_image->magick,"JPEG",MaxTextExtent);
119820fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
119853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  Creating blob.");
119860fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=ImageToBlob(jpeg_image_info,jpeg_image,&length,&image->exception);
119880fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
119903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
119913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11992e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Successfully read jpeg_image into a blob, length=%.20g.",
11993e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        (double) length);
119943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
119953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
11996e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "  Write JDAT chunk, length=%.20g.",(double) length);
119973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
119980fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
119993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write JDAT chunk(s) */
12000bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  (void) WriteBlobMSBULong(image,(size_t) length);
120013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_JDAT);
1200203812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_JDAT,length);
120033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
120043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,length,blob);
120053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(crc32(0,chunk,4),blob,(uInt) length));
120063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image=DestroyImage(jpeg_image);
120083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RelinquishUniqueFileResource(jpeg_image_info->filename);
120093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  jpeg_image_info=DestroyImageInfo(jpeg_image_info);
120103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  blob=(unsigned char *) RelinquishMagickMemory(blob);
120113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write any JNG-chunk-e profiles */
12013cf002022280cc4dedb2748ad6f415aac1d44f530glennrp  (void) Magick_png_write_chunk_from_profile(image,"JNG-chunk-e",logging);
120143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /* Write IEND chunk */
120163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,0L);
120173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PNGType(chunk,mng_IEND);
1201803812ae402fb53d548f0e1d7d14720768f803c2dglennrp  LogPNGChunk(logging,mng_IEND,0);
120193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,chunk);
120203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
120213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
120233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
120243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      "  exit WriteOneJNGImage()");
120250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
120263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
120273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
120283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
120313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
120333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
120343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
120353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e J N G I m a g e                                                 %
120363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
120373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
120383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
120393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WriteJNGImage() writes a JPEG Network Graphics (JNG) image file.
120423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  JNG support written by Glenn Randers-Pehrson, glennrp@image...
120443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteJNGImage method is:
120463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120471e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WriteJNGImage(const ImageInfo *image_info,
120481e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
120493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
120513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
120533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
120553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
120561e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
120571e178e70fb3c956f9fc1e30c3ba863e882666465cristy%
120583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
120601e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WriteJNGImage(const ImageInfo *image_info,Image *image,
120611e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
120623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
120633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1206421f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
1206503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging,
120663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
120673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
120693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
120703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
120733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
120753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
120763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
120773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
120783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12079fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteJNGImage()");
120803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
120813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
120823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
120833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
120863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1208873bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
120893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
120903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
120913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
120923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
120933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
120943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
120953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
120963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
120973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
120983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,8,(const unsigned char *) "\213JNG\r\n\032\n");
120993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=WriteOneJNGImage(mng_info,image_info,image);
121013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
121023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CatchImageException(image);
121043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
121053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
121063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteJNGImage()");
121073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
121083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
121093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
121103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121111e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image,
121121e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
121133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
121143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
121153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *option;
121163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
121183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *next_image;
121193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1212121f0e6211a440c0f96134ea25a1bfe7c5f91c29cglennrp    have_mng_structure,
121223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
121233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1212403812ae402fb53d548f0e1d7d14720768f803c2dglennrp  volatile MagickBooleanType
1212503812ae402fb53d548f0e1d7d14720768f803c2dglennrp    logging;
1212603812ae402fb53d548f0e1d7d14720768f803c2dglennrp
121273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfo
121283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *mng_info;
121293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
121313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image_count,
121323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_iterations,
121333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_matte;
121343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile int
121363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
121373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
121383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_local_plte,
121393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
121403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    all_images_are_gray,
121413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    need_defi,
121423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    use_global_plte;
121433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12144bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
121453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
121463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
121483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    chunk[800];
121493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  volatile unsigned int
121513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng,
121523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_mng;
121533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12154bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  volatile size_t
121553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    scene;
121563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12157bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
121583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    final_delay=0,
121593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    initial_delay;
121603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12161d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#if (PNG_LIBPNG_VER < 10200)
121623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (image_info->verbose)
121633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      printf("Your PNG library (libpng-%s) is rather old.\n",
121643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNG_LIBPNG_VER_STRING);
121653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
121663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
121683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
121693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
121703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
121713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
121723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
121733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
121743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
12175fd05d626fbb7efa0aeff3755d902b5bcdb89b152glennrp  logging=LogMagickEvent(CoderEvent,GetMagickModule(),"Enter WriteMNGImage()");
121763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
121773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
121783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
121793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
121813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate a MngInfo structure.
121823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
121833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickFalse;
1218473bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  mng_info=(MngInfo *) AcquireMagickMemory(sizeof(MngInfo));
121853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (mng_info == (MngInfo *) NULL)
121863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
121873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
121883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize members of the MngInfo structure.
121893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
121903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(mng_info,0,sizeof(MngInfo));
121913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->image=image;
121923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  have_mng_structure=MagickTrue;
121933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_mng=LocaleCompare(image_info->magick,"MNG") == 0;
121943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
121953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
121963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * See if user has requested a specific PNG subformat to be used
121973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * for all of the PNGs in the MNG being written, e.g.,
121983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
121993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *    convert *.png png8:animation.mng
122003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   *
122013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * To do: check -define png:bit_depth and png:color_type as well,
122023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * or perhaps use mng:bit_depth and mng:color_type instead for
122033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   * global settings.
122043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   */
122053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png8=LocaleCompare(image_info->magick,"PNG8") == 0;
122073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png24=LocaleCompare(image_info->magick,"PNG24") == 0;
122083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->write_png32=LocaleCompare(image_info->magick,"PNG32") == 0;
122093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  write_jng=MagickFalse;
122113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->compression == JPEGCompression)
122123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    write_jng=MagickTrue;
122133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->adjoin=image_info->adjoin &&
122153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (GetNextImageInList(image) != (Image *) NULL) && write_mng;
122163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
122183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /* Log some info about the input */
122203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Image
122213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
122223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "  Checking input image(s)");
122250fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12227e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy        "    Image_info depth: %.20g",(double) image_info->depth);
122280fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        "    Type: %d",image_info->type);
122313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      scene=0;
122333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
122343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
122353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12236e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "    Scene: %.20g",(double) scene++);
122370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12239e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy          "      Image depth: %.20g",(double) p->depth);
122400fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->matte)
122423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: True");
122440fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
122463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Matte: False");
122480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->storage_class == PseudoClass)
122503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: PseudoClass");
122520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
122543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Storage class: DirectClass");
122560fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (p->colors)
122583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12259e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy            "      Number of colors: %.20g",(double) p->colors);
122600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
122623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
122633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            "      Number of colors: unspecified");
122640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
122653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->adjoin == MagickFalse)
122663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
122673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
122683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
122693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  use_global_plte=MagickFalse;
122713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  all_images_are_gray=MagickFalse;
122723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
122733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_local_plte=MagickTrue;
122743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
122753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_defi=MagickFalse;
122763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  need_matte=MagickFalse;
122773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->framing_mode=1;
122783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->old_framing_mode=1;
122793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
122813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_info->page != (char *) NULL)
122823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
122843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Determine image bounding box.
122853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
122863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SetGeometry(image,&mng_info->page);
122873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ParseMetaGeometry(image_info->page,&mng_info->page.x,
122883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            &mng_info->page.y,&mng_info->page.width,&mng_info->page.height);
122893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
122903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
122913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
122923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned int
122933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        need_geom;
122943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
122953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      unsigned short
122963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        red,
122973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        green,
122983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        blue;
122993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->page=image->page;
123013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_geom=MagickTrue;
123023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (mng_info->page.width || mng_info->page.height)
123033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         need_geom=MagickFalse;
123043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
123053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Check all the scenes.
123063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
123073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      initial_delay=image->delay;
123083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_iterations=MagickFalse;
123093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_chrms=image->chromaticity.red_primary.x != 0.0;
123103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_physs=MagickTrue,
123113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_gammas=MagickTrue;
123123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_srgbs=MagickTrue;
123133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_backgrounds=MagickTrue;
123143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_count=0;
123153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
123163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
123173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      all_images_are_gray=MagickTrue;
123183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      mng_info->equal_palettes=MagickFalse;
123193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      need_local_plte=MagickFalse;
123203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
123213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (next_image=image; next_image != (Image *) NULL; )
123223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
123233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_geom)
123243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
123253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->columns+next_image->page.x) > mng_info->page.width)
123263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.width=next_image->columns+next_image->page.x;
123270fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->rows+next_image->page.y) > mng_info->page.height)
123293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->page.height=next_image->rows+next_image->page.y;
123303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
123310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->page.x || next_image->page.y)
123333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_defi=MagickTrue;
123340fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->matte)
123363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_matte=MagickTrue;
123370fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((int) next_image->dispose >= BackgroundDispose)
123393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (next_image->matte || next_image->page.x || next_image->page.y ||
123403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              ((next_image->columns < mng_info->page.width) &&
123413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (next_image->rows < mng_info->page.height)))
123423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->need_fram=MagickTrue;
123430fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (next_image->iterations)
123453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickTrue;
123460fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        final_delay=next_image->delay;
123480fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (final_delay != initial_delay || final_delay > 1UL*
123503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           next_image->ticks_per_second)
123513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->need_fram=1;
123520fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
123543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
123553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
123563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          check for global palette possibility.
123573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
123583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (image->matte != MagickFalse)
123593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           need_local_plte=MagickTrue;
123600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (need_local_plte == 0)
123623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
123633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (ImageIsGray(image) == MagickFalse)
123643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              all_images_are_gray=MagickFalse;
123653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,next_image);
123663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (use_global_plte == 0)
123673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              use_global_plte=mng_info->equal_palettes;
123683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            need_local_plte=!mng_info->equal_palettes;
123693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
123703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
123713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (GetNextImageInList(next_image) != (Image *) NULL)
123723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
123733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->background_color.red !=
123743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.red ||
123753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.green !=
123763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.green ||
123773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->background_color.blue !=
123783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->background_color.blue)
123793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_backgrounds=MagickFalse;
123800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->gamma != next_image->next->gamma)
123823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_gammas=MagickFalse;
123830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (next_image->rendering_intent !=
123853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                next_image->next->rendering_intent)
123863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_srgbs=MagickFalse;
123870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((next_image->units != next_image->next->units) ||
123893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->x_resolution != next_image->next->x_resolution) ||
123903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (next_image->y_resolution != next_image->next->y_resolution))
123913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              mng_info->equal_physs=MagickFalse;
123920fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
123933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_chrms)
123943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
123953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                if (next_image->chromaticity.red_primary.x !=
123963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.x ||
123973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.red_primary.y !=
123983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.red_primary.y ||
123993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.x !=
124003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.x ||
124013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.green_primary.y !=
124023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.green_primary.y ||
124033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.x !=
124043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.x ||
124053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.blue_primary.y !=
124063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.blue_primary.y ||
124073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.x !=
124083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.x ||
124093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->chromaticity.white_point.y !=
124103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    next_image->next->chromaticity.white_point.y)
124113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  mng_info->equal_chrms=MagickFalse;
124123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
124133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
124143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image_count++;
124153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        next_image=GetNextImageInList(next_image);
124163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
124173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (image_count < 2)
124183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
124193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_backgrounds=MagickFalse;
124203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_chrms=MagickFalse;
124213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_gammas=MagickFalse;
124223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs=MagickFalse;
124233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_physs=MagickFalse;
124243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          use_global_plte=MagickFalse;
124253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
124263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_local_plte=MagickTrue;
124273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
124283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          need_iterations=MagickFalse;
124293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
124300fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram == MagickFalse)
124323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
124333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
124343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Only certain framing rates 100/n are exactly representable without
124353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           the FRAM chunk but we'll allow some slop in VLC files
124363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
124373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay == 0)
124383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
124393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_iterations != MagickFalse)
124403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
124413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 /*
124423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   It's probably a GIF with loop; don't run it *too* fast.
124433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 */
124440261712cdc8fb4765add50146936e3ba2cb9fefaglennrp                 if (mng_info->adjoin)
12445d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   {
12446d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     final_delay=10;
12447d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                     (void) ThrowMagickException(&image->exception,
12448d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                        GetMagickModule(),CoderWarning,
12449d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       "input has zero delay between all frames; assuming",
12450d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                       " 10 cs `%s'","");
12451d908de4208e47f6b6ddb7c288b50d8f6d8845bb2glennrp                   }
124523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
124533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
124543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               mng_info->ticks_per_second=0;
124553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
124563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay != 0)
12457cf002022280cc4dedb2748ad6f415aac1d44f530glennrp           mng_info->ticks_per_second=(png_uint_32)
12458cf002022280cc4dedb2748ad6f415aac1d44f530glennrp              (image->ticks_per_second/final_delay);
124593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 50)
124603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=2;
124610fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 75)
124633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->ticks_per_second=1;
124640fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (final_delay > 125)
124663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;
124670fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_defi && final_delay > 2 && (final_delay != 4) &&
124693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 5) && (final_delay != 10) && (final_delay != 20) &&
124703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (final_delay != 25) && (final_delay != 50) && (final_delay !=
124713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               1UL*image->ticks_per_second))
124723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           mng_info->need_fram=MagickTrue;  /* make it exact; cannot be VLC */
124733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
124740fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
124753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (mng_info->need_fram != MagickFalse)
124763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->ticks_per_second=1UL*image->ticks_per_second;
124773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
124783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        If pseudocolor, we should also check to see if all the
124793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        palettes are identical and write a global PLTE if they are.
124803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ../glennrp Feb 99.
124813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
124823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
124833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MNG version 1.0 signature and MHDR chunk.
124843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
124853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,8,(const unsigned char *) "\212MNG\r\n\032\n");
124863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,28L);  /* chunk data length=28 */
124873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGType(chunk,mng_MHDR);
1248803812ae402fb53d548f0e1d7d14720768f803c2dglennrp     LogPNGChunk(logging,mng_MHDR,28L);
124894e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+4,(png_uint_32) mng_info->page.width);
124904e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy     PNGLong(chunk+8,(png_uint_32) mng_info->page.height);
124913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+12,mng_info->ticks_per_second);
124923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+16,0L);  /* layer count=unknown */
124933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+20,0L);  /* frame count=unknown */
124943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNGLong(chunk+24,0L);  /* play time=unknown   */
124953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_jng)
124963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
124973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
124983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
124993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
125003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,27L);    /* simplicity=LC+JNG */
125010fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
125033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,25L);    /* simplicity=VLC+JNG */
125043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
125050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
125073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
125083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
125093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,19L);  /* simplicity=LC+JNG, no transparency */
125100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
125123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,17L);  /* simplicity=VLC+JNG, no transparency */
125133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
125143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
125150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
125173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
125183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (need_matte)
125193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
125203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
125213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,11L);    /* simplicity=LC */
125220fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
125243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,9L);    /* simplicity=VLC */
125253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
125260fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
125283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
125293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (need_defi || mng_info->need_fram || use_global_plte)
125303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,3L);    /* simplicity=LC, no transparency */
125310fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
125333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               PNGLong(chunk+28,1L);    /* simplicity=VLC, no transparency */
125343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
125353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
125363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlob(image,32,chunk);
125373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     (void) WriteBlobMSBULong(image,crc32(0,chunk,32));
125383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     option=GetImageOption(image_info,"mng:need-cacheoff");
125393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (option != (const char *) NULL)
125403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
125413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         size_t
125423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           length;
125433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
125443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
125453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write "nEED CACHEOFF" to turn playback caching off for streaming MNG.
125463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
125473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_nEED);
125483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length=CopyMagickString((char *) chunk+4,"CACHEOFF",20);
12549bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         (void) WriteBlobMSBULong(image,(size_t) length);
1255003812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_nEED,(size_t) length);
125513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         length+=4;
125523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,length,chunk);
125533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) length));
125543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
125553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((GetPreviousImageInList(image) == (Image *) NULL) &&
125563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (GetNextImageInList(image) != (Image *) NULL) &&
125573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->iterations != 1))
125583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
125593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
125603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG TERM chunk
125613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
125623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
125633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_TERM);
1256403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_TERM,10L);
125653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[4]=3;  /* repeat animation */
125663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         chunk[5]=0;  /* show last frame when done */
125673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGLong(chunk+6,(png_uint_32) (mng_info->ticks_per_second*
125683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            final_delay/MagickMax(image->ticks_per_second,1)));
125690fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->iterations == 0)
125713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,PNG_UINT_31_MAX);
125720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
125743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32) image->iterations);
125750fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (logging != MagickFalse)
125773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
125783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12579e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy               "     TERM delay: %.20g",(double) (mng_info->ticks_per_second*
12580e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy              final_delay/MagickMax(image->ticks_per_second,1)));
125810fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->iterations == 0)
125833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12584e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     TERM iterations: %.20g",(double) PNG_UINT_31_MAX);
125850fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
125863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
125873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
12588e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy                 "     Image iterations: %.20g",(double) image->iterations);
125893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
125903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,14,chunk);
125913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
125923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
125933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
125943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       To do: check for cHRM+gAMA == sRGB, and write sRGB instead.
125953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
125963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((image->colorspace == sRGBColorspace || image->rendering_intent) &&
125973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->equal_srgbs)
125983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
125993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
126003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG sRGB chunk
126013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
126023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,1L);
126033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_sRGB);
1260403812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_sRGB,1L);
126050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->rendering_intent != UndefinedIntent)
12607e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12608cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12609e610a071534e448c46460a5aa39ede33bf56b329glennrp             (image->rendering_intent));
126100fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
12612e610a071534e448c46460a5aa39ede33bf56b329glennrp           chunk[4]=(unsigned char)
12613cf002022280cc4dedb2748ad6f415aac1d44f530glennrp             Magick_RenderingIntent_to_PNG_RenderingIntent(
12614cf002022280cc4dedb2748ad6f415aac1d44f530glennrp               (PerceptualIntent));
126150fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,5,chunk);
126173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
126183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_srgb=MagickTrue;
126193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
126200fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     else
126223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
126233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->gamma && mng_info->equal_gammas)
126243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
126263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG gAMA chunk
126273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
126283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,4L);
126293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_gAMA);
1263003812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_gAMA,4L);
1263135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*image->gamma+0.5));
126323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,8,chunk);
126333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,8));
126343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_gama=MagickTrue;
126353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_chrms)
126373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PrimaryInfo
126393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               primary;
126403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
126413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             /*
126423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                Write MNG cHRM chunk
126433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             */
126443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,32L);
126453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_cHRM);
1264603812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_cHRM,32L);
126473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.white_point;
1264835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32) (100000*primary.x+0.5));
1264935ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32) (100000*primary.y+0.5));
126503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.red_primary;
1265135ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+12,(png_uint_32) (100000*primary.x+0.5));
1265235ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+16,(png_uint_32) (100000*primary.y+0.5));
126533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.green_primary;
1265435ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+20,(png_uint_32) (100000*primary.x+0.5));
1265535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+24,(png_uint_32) (100000*primary.y+0.5));
126563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             primary=image->chromaticity.blue_primary;
1265735ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+28,(png_uint_32) (100000*primary.x+0.5));
1265835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+32,(png_uint_32) (100000*primary.y+0.5));
126593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,36,chunk);
126603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,36));
126613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             mng_info->have_write_global_chrm=MagickTrue;
126623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
126643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (image->x_resolution && image->y_resolution && mng_info->equal_physs)
126653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
126663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
126673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write MNG pHYs chunk
126683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
126693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,9L);
126703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_pHYs);
1267103812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_pHYs,9L);
126720fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (image->units == PixelsPerInchResolution)
126743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
1267535ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+4,(png_uint_32)
126763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->x_resolution*100.0/2.54+0.5));
126770fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1267835ef824baa82511126ff0072ae30eee0da9c05a3cristy             PNGLong(chunk+8,(png_uint_32)
126793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               (image->y_resolution*100.0/2.54+0.5));
126800fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[12]=1;
126823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
126830fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         else
126853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
126863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             if (image->units == PixelsPerCentimeterResolution)
126873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1268835ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32)
126893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->x_resolution*100.0+0.5));
126900fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
1269135ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32)
126923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (image->y_resolution*100.0+0.5));
126930fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=1;
126953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
126960fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
126973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             else
126983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               {
1269935ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+4,(png_uint_32) (image->x_resolution+0.5));
1270035ef824baa82511126ff0072ae30eee0da9c05a3cristy                 PNGLong(chunk+8,(png_uint_32) (image->y_resolution+0.5));
127013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 chunk[12]=0;
127023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               }
127033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,13,chunk);
127053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,13));
127063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     /*
127083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       Write MNG BACK chunk and global bKGD chunk, if the image is transparent
127093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       or does not cover the entire frame.
127103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     */
127113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if (write_mng && (image->matte || image->page.x > 0 ||
127123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         image->page.y > 0 || (image->page.width &&
127133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->page.width+image->page.x < mng_info->page.width))
127143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         || (image->page.height && (image->page.height+image->page.y
127153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         < mng_info->page.height))))
127163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
127173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,6L);
127183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_BACK);
1271903812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_BACK,6L);
127203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         red=ScaleQuantumToShort(image->background_color.red);
127213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         green=ScaleQuantumToShort(image->background_color.green);
127223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         blue=ScaleQuantumToShort(image->background_color.blue);
127233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+4,red);
127243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+6,green);
127253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGShort(chunk+8,blue);
127263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,10,chunk);
127273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
127283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         if (mng_info->equal_backgrounds)
127293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           {
127303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,6L);
127313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_bKGD);
1273203812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_bKGD,6L);
127333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,10,chunk);
127343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,10));
127353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           }
127363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
127393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     if ((need_local_plte == MagickFalse) &&
127403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (image->storage_class == PseudoClass) &&
127413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (all_images_are_gray == MagickFalse))
127423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       {
12743bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         size_t
127443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           data_length;
127453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
127463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         /*
127473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           Write MNG PLTE chunk
127483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         */
127493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         data_length=3*image->colors;
127503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,data_length);
127513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         PNGType(chunk,mng_PLTE);
1275203812ae402fb53d548f0e1d7d14720768f803c2dglennrp         LogPNGChunk(logging,mng_PLTE,data_length);
127530fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12754bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy         for (i=0; i < (ssize_t) image->colors; i++)
127553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
127563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red) & 0xff;
127573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green) & 0xff;
127583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue) & 0xff;
127593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
127600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
127613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlob(image,data_length+4,chunk);
127623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) WriteBlobMSBULong(image,crc32(0,chunk,(uInt) (data_length+4)));
127633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         mng_info->have_write_global_plte=MagickTrue;
127643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       }
127653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
127673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scene=0;
127683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->delay=0;
127693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
127703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
127713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  mng_info->equal_palettes=MagickFalse;
127723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
127733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  do
127743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
127753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (mng_info->adjoin)
127763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
127773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) || \
127783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    defined(PNG_MNG_FEATURES_SUPPORTED)
127793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
127803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      If we aren't using a global palette for the entire MNG, check to
127813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      see if we can use one for two or more consecutive images.
127823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
127833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_local_plte && use_global_plte && !all_images_are_gray)
127843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
127853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (mng_info->IsPalette)
127863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
127873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            /*
127883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              When equal_palettes is true, this image has the same palette
127893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              as the previous PseudoClass image
127903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            */
127913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->have_write_global_plte=mng_info->equal_palettes;
127923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            mng_info->equal_palettes=PalettesAreEqual(image,image->next);
127933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (mng_info->equal_palettes && !mng_info->have_write_global_plte)
127943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
127953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                /*
127963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  Write MNG PLTE chunk
127973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                */
12798bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                size_t
127993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  data_length;
128003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                data_length=3*image->colors;
128023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,data_length);
128033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                PNGType(chunk,mng_PLTE);
1280403812ae402fb53d548f0e1d7d14720768f803c2dglennrp                LogPNGChunk(logging,mng_PLTE,data_length);
128050fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
12806bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy                for (i=0; i < (ssize_t) image->colors; i++)
128073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
128083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[4+i*3]=ScaleQuantumToChar(image->colormap[i].red);
128093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[5+i*3]=ScaleQuantumToChar(image->colormap[i].green);
128103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  chunk[6+i*3]=ScaleQuantumToChar(image->colormap[i].blue);
128113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
128120fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
128133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlob(image,data_length+4,chunk);
128143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) WriteBlobMSBULong(image,crc32(0,chunk,
128153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   (uInt) (data_length+4)));
128163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                mng_info->have_write_global_plte=MagickTrue;
128173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
128183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
128193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          mng_info->have_write_global_plte=MagickFalse;
128213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
128223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
128233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (need_defi)
128243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12825bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        ssize_t
128263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_x,
128273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          previous_y;
128283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (scene)
128303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
128313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=mng_info->page.x;
128323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=mng_info->page.y;
128333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
128343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
128353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
128363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_x=0;
128373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            previous_y=0;
128383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
128393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        mng_info->page=image->page;
128403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((mng_info->page.x !=  previous_x) ||
128413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (mng_info->page.y != previous_y))
128423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
128433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,12L);  /* data length=12 */
128443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGType(chunk,mng_DEFI);
1284503812ae402fb53d548f0e1d7d14720768f803c2dglennrp             LogPNGChunk(logging,mng_DEFI,12L);
128463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[4]=0; /* object 0 MSB */
128473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[5]=0; /* object 0 LSB */
128483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[6]=0; /* visible  */
128493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             chunk[7]=0; /* abstract */
128503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+8,(png_uint_32) mng_info->page.x);
128513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             PNGLong(chunk+12,(png_uint_32) mng_info->page.y);
128523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlob(image,16,chunk);
128533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             (void) WriteBlobMSBULong(image,crc32(0,chunk,16));
128543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
128553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
128563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
128573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   mng_info->write_mng=write_mng;
128593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if ((int) image->dispose >= 3)
128613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     mng_info->framing_mode=3;
128623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
128633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (mng_info->need_fram && mng_info->adjoin &&
128643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ((image->delay != mng_info->delay) ||
128653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (mng_info->framing_mode != mng_info->old_framing_mode)))
128663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
128673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (image->delay == mng_info->delay)
128683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
128693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
128703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the new framing mode.
128713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
128723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
128733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1287403812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,1L);
128753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
128763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,5,chunk);
128773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
128783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
128793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       else
128803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         {
128813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           /*
128823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             Write a MNG FRAM chunk with the delay.
128833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           */
128843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,10L);  /* data length=10 */
128853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGType(chunk,mng_FRAM);
1288603812ae402fb53d548f0e1d7d14720768f803c2dglennrp           LogPNGChunk(logging,mng_FRAM,10L);
128873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[4]=(unsigned char) mng_info->framing_mode;
128883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[5]=0;  /* frame name separator (no name) */
128893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[6]=2;  /* flag for changing default delay */
128903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[7]=0;  /* flag for changing frame timeout */
128913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[8]=0;  /* flag for changing frame clipping */
128923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           chunk[9]=0;  /* flag for changing frame sync_id */
128933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           PNGLong(chunk+10,(png_uint_32)
128943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             ((mng_info->ticks_per_second*
128953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             image->delay)/MagickMax(image->ticks_per_second,1)));
128963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlob(image,14,chunk);
128973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           (void) WriteBlobMSBULong(image,crc32(0,chunk,14));
128984e5bc84ff8bf274c4d9206d5e6ffd1a5e5d75335cristy           mng_info->delay=(png_uint_32) image->delay;
128993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         }
129003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       mng_info->old_framing_mode=mng_info->framing_mode;
129013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
129023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(JNG_SUPPORTED)
129043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (image_info->compression == JPEGCompression)
129053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
129063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       ImageInfo
129073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         *write_info;
129083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
129103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing JNG object.");
129123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       /* To do: specify the desired alpha compression method. */
129133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=CloneImageInfo(image_info);
129143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info->compression=UndefinedCompression;
129153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOneJNGImage(mng_info,write_info,image);
129163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       write_info=DestroyImageInfo(write_info);
129173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
129183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
129193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
129203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     {
129213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       if (logging != MagickFalse)
129223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
129233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy           "  Writing PNG object.");
129242f2e514554975d510c88df54de98c6cdc1080f1cglennrp
12925b9cfe27bef51dbbd1f05aef89c767749d7e37864glennrp       mng_info->need_blob = MagickFalse;
129268d3d6e584829223ac5f6e6653c3caa38a2562a74glennrp       mng_info->ping_preserve_colormap = MagickFalse;
129272f2e514554975d510c88df54de98c6cdc1080f1cglennrp
129282f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* We don't want any ancillary chunks written */
129292f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_bKGD=MagickTrue;
129302f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_cHRM=MagickTrue;
12931a0ed009a1e9480ac6f3f4520e9ef29d6d37e27dcglennrp       mng_info->ping_exclude_date=MagickTrue;
129322f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_EXIF=MagickTrue;
129332f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_gAMA=MagickTrue;
129342f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_iCCP=MagickTrue;
129352f2e514554975d510c88df54de98c6cdc1080f1cglennrp       /* mng_info->ping_exclude_iTXt=MagickTrue; */
129362f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_oFFs=MagickTrue;
129372f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_pHYs=MagickTrue;
129382f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_sRGB=MagickTrue;
129392f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_tEXt=MagickTrue;
12940a1e3b7b4887860a199d00bddbf4b12e0a93ee1e5glennrp       mng_info->ping_exclude_tRNS=MagickTrue;
129412f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_vpAg=MagickTrue;
129422f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zCCP=MagickTrue;
129432f2e514554975d510c88df54de98c6cdc1080f1cglennrp       mng_info->ping_exclude_zTXt=MagickTrue;
129442f2e514554975d510c88df54de98c6cdc1080f1cglennrp
129453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy       status=WriteOnePNGImage(mng_info,image_info,image);
129463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
129473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
129483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
129493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
129503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MngInfoFreeStruct(mng_info,&have_mng_structure);
129513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) CloseBlob(image);
129523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(MagickFalse);
129533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
129543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) CatchImageException(image);
129553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetNextImageInList(image) == (Image *) NULL)
129563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
129573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    image=SyncNextImageInList(image);
129583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status=SetImageProgress(image,SaveImagesTag,scene++,
129593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      GetImageListLength(image));
129600fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
129623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
129630fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } while (mng_info->adjoin);
129650fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (write_mng)
129673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
129683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (GetPreviousImageInList(image) != (Image *) NULL)
129693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        image=GetPreviousImageInList(image);
129703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
129713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the MEND chunk.
129723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
129733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,0x00000000L);
129743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      PNGType(chunk,mng_MEND);
1297503812ae402fb53d548f0e1d7d14720768f803c2dglennrp      LogPNGChunk(logging,mng_MEND,0L);
129763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlob(image,4,chunk);
129773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobMSBULong(image,crc32(0,chunk,4));
129783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
129793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
129803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Relinquish resources.
129813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
129823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
129833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MngInfoFreeStruct(mng_info,&have_mng_structure);
129840fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (logging != MagickFalse)
129863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"exit WriteMNGImage()");
129870fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
129893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12990d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#else /* PNG_LIBPNG_VER > 10011 */
1299139992b4dd9b12ef752d55b8e402c069698851f72glennrp
129923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WritePNGImage(const ImageInfo *image_info,Image *image)
129933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
129943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=image;
129953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  printf("Your PNG library is too old: You have libpng-%s\n",
129963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     PNG_LIBPNG_VER_STRING);
129970fe50b47f88ea0fc74b8bdb0e552fc7c58e2b5a0glennrp
129983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ThrowBinaryException(CoderError,"PNG library is too old",
129993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     image_info->filename);
130003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1300139992b4dd9b12ef752d55b8e402c069698851f72glennrp
130023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType WriteMNGImage(const ImageInfo *image_info,Image *image)
130033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
130043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(WritePNGImage(image_info,image));
130053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13006d5045b44ae266ec7d6d2fca5e7c8a69a28938ec4glennrp#endif /* PNG_LIBPNG_VER > 10011 */
130073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
13008